-5

The program creates thread t0 which spawns thread t1 and subsequently threads t2 and t3 are created.After the execution of thread t3and the application never returns to the other threads spawned earlier(t0,t1,t2) and they are left stuck.

Why are the threads t0, t1, and t2 suspended?

     public class Cult extends Thread 
            {  
                private String[] names = {"t1", "t2", "t3"};
                static int count = 0;
                public void run() 
                {
                    for(int i = 0; i < 100; i++) 
                    {
                        if(i == 5 && count < 3) 
                        {
                            Thread t = new Cult(names[count++]);
                            t.start();
                            try{
                                Thread.currentThread().join();
                            }
                            catch(InterruptedException e)
                            {
                                e.printStackTrace();
                            }
                        }
                        System.out.print(Thread.currentThread().getName() + " ");
                    } 
                 }

                 public static void main(String[] a`)
                 {
                     new Cult("t0").start();
                 }
            }
Sameer Sarmah
  • 1,052
  • 4
  • 15
  • 33
  • 1
    You probably want `t.join()` not `Thread.currentThread().join();` – Gray Aug 13 '13 at 20:10
  • @Gray: That is exactly what I seek. t.join() executes properly with t3 finishing first and t0 finishing last.But what happens when we use Thread.currentThread.join()?Why t0,t1,t2 are suspended in the middle? – Sameer Sarmah Aug 13 '13 at 20:21

2 Answers2

2

The most important point you missed:

Thread.currentThread().join();

Method join in source code uses isAlive method.

public final synchronized void join(long millis) 
    ...
    if (millis == 0) {
        while (isAlive()) {
        wait(0);
        }
    ...
    }

It means that Thread.currentThread().join() will return only when Thread.currentThread() is dead.

But in your case it's impossible because of your running code in Thread.currentThread() has itself this peace of code Thread.currentThread().join(). That's why after Thread 3 completion your program should hang and nothing happens thereafter.

enter image description here

Sergii Shevchyk
  • 38,716
  • 12
  • 50
  • 61
1

Why are the threads t0, t1, and t2 suspended? The execution of thread t3 completes.

t3 completes because it is not trying to fork a 4th thread and therefore is not trying to join() with it's own thread. The following line will never return so t0, t1, and t2 all stop there and wait forever:

Thread.currentThread().join();

This is asking the current thread to wait for itself to finish which doesn't work. I suspect that you meant to say t.join(); which is waiting for the thread that was just forked to finish.

Here are some other thoughts about your code in no apparent order:

  • You should consider implements Runnable instead of extends Thread. See here: "implements Runnable" vs. "extends Thread"

  • You are using the shared static variable count in multiple threads without any protection of locking. The best solution is to use an AtomicInteger instead of a int. You probably don't have a problem here because each thread is modifying count and then forking another thread but if you tried to fork 2 threads, this would be a real problem because of data race conditions.

  • I'm not sure why you are only spawning another thread if(i == 5 && count < 3). i is only going to be 5 once in that loop. Is that really what you intended?

  • String[] names = {"t1", "t2", "t3"}; fields are recommended to be declared at the top of classes. Otherwise they get buried in the code and get lost.

  • In main you start a Cult thread and then the main thread finishes. This is unnecessary and you can just call cult.run(); in main instead and use the main thread.

  • Cult(String s) { super(s); } there is no point in having a constructor that calls the super constructor with the same arguments. This can be removed.

  • This is debatable but I tend to put main method at the top of the class and not bury it since it is the "entrance" method. Same thing with constructors. Those should be above the run() method.

  • catch(Exception e) {} is a really bad pattern. At the very least you should do a e.printStackTrace(); or log it somehow. Catching and just dropping exceptions hides a lot of problems. Also, catching Exception should be changed to catch(InterruptedException e). You want to restrict your catch blocks just the exceptions thrown by the block otherwise this may again hide problems in the future if you copy and paste that block somewhere.

  • More a good practice but never use constants like 3 that have to match another data item. In this case it would be better to use names.length which is 3. THis means that you don't need to change 2 places in the code if you want to increase the number of threads. You could also have the name be "t" + count and get rid of the names array altogether.

Community
  • 1
  • 1
Gray
  • 115,027
  • 24
  • 293
  • 354