简体   繁体   中英

Join() in multithreading

According to join definition, the join thread executes till its execution is complete and is not prempted in the middle (correct me if i am wrong) .But in the following code: the join thread t1 doesnt stop the main thread to take the control in between the execution of t1. why so ?

public class JavaAtomic {

public static void main(String[] args) throws InterruptedException {

    ProcessingThread pt = new ProcessingThread();
    Thread t1 = new Thread(pt, "t1");
    t1.start();
    Thread t2 = new Thread(pt, "t2");
    t2.start();
    t1.join();
    t2.join();
    System.out.println("Processing count=" + pt.getCount());
}

}


  class ProcessingThread implements Runnable {
   private int count;


@Override
public void run() {
    for (int i = 1; i < 5; i++) {
        processSomething(i);
        count++;
   System.out.println(Thread.currentThread()+"---"+getCount())   ;
    }
}


public int getCount() {
    return this.count;
}


private void processSomething(int i) {
    // processing some job
    try {
        Thread.sleep(i * 1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

}

output:

Thread[t1,5,main]---1
Thread[t2,5,main]---2
Thread[t1,5,main]---3
Thread[t2,5,main]---4
Thread[t1,5,main]---5
Thread[t2,5,main]---5
Thread[t2,5,main]---6
Thread[t1,5,main]---7
Processing count=7

Many Thanks Jayendra

Here's what is happening in your example:

  • Main thread starts running, instantiates and kicks off t1 and t2
  • t1 runs a little
  • t2 runs a little
  • The main thread joins on t1 and blocks until t1 finishes
  • t1 and t2 keep doing their thing. We continue to see output from them. Main thread is blocking.
  • t1 finishes and main thread unblocks
  • Main thread joins on t2 . However, it just so happens that in your particular output example, t2 actually finished before t1 , which is entirely possible under the randomness of the thread scheduler. So, the main thread doesn't block on this second join() call because t2 is already done.
  • The main thread runs to completion and program exits.

ADDITION

The above answer is unchanged. However I noticed a thread safety issue in your code. You have multiple threads incrementing the count variable in the shared ProcessThread instance by using the ++ operator. Please note that ++ is not atomic (see this article ), because it really consists of four operations: reading the current value of count , adding 1 to it, writing the new value back to count , and returning the value to the caller. In the gaps between those four operations, the thread scheduler could pre-empt the current thread and slip in another one carrying an outdated value read from count . Try increasing the number of threads and decreasing the time in your sleep() call and you will see the current count number appear inconsistent (same number may appear more than once, lower before higher, etc.) count becomes subject to race conditions between threads. The solution is to either enclose all reads/writes to count in synchronized , or to use a java.util.concurrent.atomic.AtomicInteger .

Join stops the thread that calls join. It has no effect on the thread joined.

when you call t1.join(), it won't have any effect on t1's execution. ie It can't stop t1. t1.join() will wait for t1 to finish and then go forward in the execution.

When main thread reaches the code t1.join() both t1 and t2 have been started and now main thread will wait for t1 to finish. But we can't predict the behaviour of running of t1 and t2, we can only assure that the last line of main function System.out.println("Processing count=" + pt.getCount()); will execute only after thread t1 and t2 finish execution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM