-2

I've read the Thread documentation and looked over a number of examples, but I'm not able to get my code to function properly. I want to guarantee that Threads are executed in the order t2, t3, t1, and am trying to use the join() method to do so.

From what I understand, join() will ensure that the instance of the Thread it is called on will run until killed before proceeding with the next Thread's execution. Here's my code:

public class ThreadyKrueger extends Thread {

private Thread t;
private String threadName;

public ThreadyKrueger(String name) {
    this.threadName = name;
    System.out.println("Creating thead, \"" + this.threadName + "\"");
}
@Override
public void run() {
    try {
        System.out.println("Job being run by " + this.threadName);
        Thread.sleep(200);
    } catch (InterruptedException e) {
        System.out.println("Thread " + this.threadName + " interrupted!");
    }
    System.out.println(this.threadName + " exiting...");
}
@Override
public void start() {
    System.out.println("Starting " + this.threadName);
    if (t == null) {
        t = new Thread(this, this.threadName);
    }
    t.start();
}

}

public class ThreadMain {

public static void main(String[] args) throws InterruptedException {
    //ensure order is t2, t3, t1
    ThreadyKrueger t2 = new ThreadyKrueger("T2");
    ThreadyKrueger t3 = new ThreadyKrueger("T3");
    ThreadyKrueger t1 = new ThreadyKrueger("T1");        
    t2.start();
    t2.join();        
    t3.start();
    t3.join();
    t1.start();
}

And the output I'm getting varies each time, but for instance:

Creating thead, "T2"
Creating thead, "T3"
Creating thead, "T1"
Starting T2
Starting T3
Starting T1
Job being run by T2
Job being run by T3
Job being run by T1
T1 exiting...
T2 exiting...
T3 exiting...

Clearly T2 is not killed before T3 starts, and so on. What am I missing (besides a few indents and brackets that were lost in copy/paste). Thank you.

hsotweelvl
  • 85
  • 5
  • 1
    Why are you creating a `Thread` that starts another `Thread` (on which you don't `join`)? This is extremely backwards. Your `Krueger` should be a `Runnable`. – Sotirios Delimanolis Jan 09 '16 at 19:37
  • I see-- I was experimenting with both the Runnable implementation and the Thread implementation, and it seems I've mixed the two. Thanks for pointing that out. – hsotweelvl Jan 09 '16 at 19:39
  • 2
    If you want a specific execution order **why are you using threads?** – user207421 Jan 09 '16 at 19:41
  • I realize that. This is merely for learning purposes to understand what the `join()` method does. – hsotweelvl Jan 09 '16 at 19:43
  • Just a general question as a newcomer to SO: What can I do to improve my questions for future reference, as this is being down-voted? – hsotweelvl Jan 09 '16 at 19:54

3 Answers3

1

You start a thread from another thread, but join on the starting thread (ThreadyKrueger). ThreadyKrueger finishes right after starting your inner thread which then executes the run() method..

Use Runnable instead of subclassing Thread, to avoid such problems.

Also, I don't see a point for running tasks sequentially in separate threads. I'd create a list/queue of Runnable and process this in a loop instead.

Martin C.
  • 12,140
  • 7
  • 40
  • 52
  • Thanks. I was trying both implementations (extending `Thread` and implementing `Runnable`, and mistakenly mixed some code between the two. Obvious now that it's been pointed out! – hsotweelvl Jan 09 '16 at 19:42
1

The thread you created in the main are correctly executed in order, but as each one is launching their own thread, these ran in concurrency... There is no need to create these "sub-threads". Remove the overridden start method.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
1

In your main method, when you execute for example t2.start, you are inside creating another thread, when you execute t.start();

A better aproach, is to remove the start method in your ThreadyKrueger class.

Alejandro Goñi
  • 532
  • 1
  • 3
  • 14