Is it possible such a race condition waiting for a thread to complete a task?
My unexperience with concurrency is quite clear, and I'm looking here for some help.
I was writing a multithreaded application in Java while I was assailed by a doubt. Please look at this sample code (mixing pseudocode and Java):
Thead 1 body (portion):
/* It creates and starts thread Thread 2 */
if (!thread2.taskCompleted)
thread2.wait();
/* continue execution... */
Thead 2 body:
class Thread2 extends Thread {
volatile boolean taskCompleted = false;
public void run() {
/* It executes a complex task... */
t开发者_运维技巧askCompleted = true;
notifyAll(); // notify waiting threads
}
}
My concern is simple as that: what happens if the statements are executed in that order:
- Thread 1 starts Thread 2
- Thread 2 does some stuff, but doesn't complete the task
- Thread 1 reads taskCompleted as false
- Thread 2 completes the task, raises the taskCompleted flag, and notifies (nobody)
- Thread 1 starts waiting. And never ends.
Please let me know if you have any ideas and/or it is a well-known scenario (exact duplicate?)
The usage of the taskCompleted
flag and wait()/nofiyAll()
must be protected by a lock to avoid the scenario you describe.
/* It creates and starts thread Thread 2 */
synchronized (thread2) {
if (!thread2.taskCompleted)
thread2.wait();
}
/* continue execution... */
and
class Thread2 extends Thread {
boolean taskCompleted = false;
public void run() {
/* It executes a complex task... */
synchronized (this) {
taskCompleted = true;
notifyAll(); // notify waiting threads
}
}
}
I think these blocks should be synchronized, see http://download.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html.
Or you could use something like CountDownLatch, see: http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html
In addition to what others answered before, from my personal experience avoid as much as you can (unless you are building custom synchronizers) using wait , notify etc. There are many good and sufficient classes like semaphores, barrier, latch, lock or general synchronized. They in 90% of the cases are sufficient. In above case you could use synchonized(this) or with any other variable. Or could use ReenterantLock
精彩评论