Reputation: 2316
So for my own understanding, I wrote two threads each of which prints a line to output.
However, I wanted to make the two threads so that they print one after another. Let's say t1
and t2
. If t1
prints its own message then it has to wait for the other thread to print theirs. Now I manage to make it working by experimenting but there is something I don't understand.
This is my code:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Multithread {
public static void main(String [] m) throws InterruptedException, ExecutionException {
Lock lock = new ReentrantLock();
Condition c1 = lock.newCondition();
Runnable t1 = new Runnable() {
@Override
public void run() {
for(int i : new int[] {1,2,3,4,5}) {
lock.lock();
try {
c1.signal();
System.out.println("In thread 1 - " + i);
try {
c1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} finally {
c1.signal();
lock.unlock();
}
}
}
};
Callable<String> t2 = new Callable<String>() {
@Override
public String call() throws Exception {
for(int i : new int[] {1,2,3,4,5}) {
lock.lock();
try {
c1.signal();
System.out.println("In callable 2 - " + i);
try {
c1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} finally {
c1.signal();
lock.unlock();
}
}
return "This is callable";
}
};
new Thread(t1, "t1").start();
FutureTask<String> task = new FutureTask<>(t2);
new Thread(task, "t2").start();
//c1.signalAll();
System.out.println(task.get());
}
}
Please ignore the code is used Callable and Runnable instead of using one type. So this is my interpretation of this code:
signal()
s other threads and then it prints its message and then it waits at c1.await()
unlock()
edBut to my surprise, it works as I wanted to and each thread prints its message on a turn basis, that is:
Another thing that I don't understand is the fact that InterruptedException
never happens and the printStackTrace()
never reached!
Can someone please explain what is happening here?
Upvotes: 0
Views: 856
Reputation: 27190
With this logic, t2 should never print its message because t1 is waiting and hasn't unlock() ed
I think what you're missing is that condition.await()
unlocks the lock
from which condition
was obtained, and then it guarantees to re-lock the lock
before it returns.
Upvotes: 1