Reputation: 36984
I have the following method test where I start threads:
public static void main(String[] args) throws InterruptedException {
List<Thread> threads = new ArrayList<>();
final CyclicBarrier cyclicBarrier = new CyclicBarrier(1);
Thread thread = new Thread(new CallbackThread(cyclicBarrier, threads));
threads.add(thread);
thread.start();
}
CallBack thread looks like this:
class CallbackThread implements Runnable {
CyclicBarrier cyclicBarrier;
List<Thread> threads;
CallbackThread(CyclicBarrier cyclicBarrier, List<Thread> threads) {
this.cyclicBarrier = cyclicBarrier;
this.threads = threads;
}
@Override
public void run() {
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (BrokenBarrierException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
System.out.println("Threads started");
for (Thread thread1 : threads) {
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
System.out.println("Threads finished");
}
}
When I run application I see following output:
Threads started
and application hangs.
I don understand why.
If to replace join logic to main method - all goods well.
public static void main(String[] args) throws InterruptedException {
List<Thread> threads = new ArrayList<>();
final CyclicBarrier cyclicBarrier = new CyclicBarrier(1);
Thread thread = new Thread(new CallbackThread(cyclicBarrier, threads));
threads.add(thread);
thread.start();
for (Thread thread1 : threads) {
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
System.out.println("Threads finished");
}
Can you explain this difference.
IMHO it should work same.
Upvotes: 0
Views: 154
Reputation: 41945
You are joining on self. That's why the program never ends.
When you call the join()
from Main thread, then main thread is trying to join the thread it created which is CallableThread
. So it is proper.
But when you join in CallableThread
, then you are passing threads[]
which contains the reference to itself. So it is joining itself, which will not end.
Upvotes: 1
Reputation: 4872
The code from your first example calls join on its own thread. You add it to the list and the thread iterates over the list and joins every thread inside the list.
Upvotes: 2