开发者

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:

  1. Thread 1 starts Thread 2
  2. Thread 2 does some stuff, but doesn't complete the task
  3. Thread 1 reads taskCompleted as false
  4. Thread 2 completes the task, raises the taskCompleted flag, and notifies (nobody)
  5. 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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜