Reputation: 1385
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
Upvotes: 2
Views: 262
Reputation: 10833
Here's what is happening in your example:
t1
and t2
t1
runs a littlet2
runs a littlet1
and blocks until t1
finishest1
and t2
keep doing their thing. We continue to see output from them. Main thread is blocking.t1
finishes and main thread unblockst2
. 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 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
.
Upvotes: 2
Reputation: 685
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.
Upvotes: 0
Reputation: 393
when you call t1.join(), it won't have any effect on t1's execution. i.e It can't stop t1. t1.join() will wait for t1 to finish and then go forward in the execution.
Upvotes: 0
Reputation: 182763
Join stops the thread that calls join. It has no effect on the thread joined.
Upvotes: 0