是否可能出现这样的竞争条件等待线程完成任务?

发布于 2024-12-03 11:15:06 字数 838 浏览 2 评论 0原文

我对并发的缺乏经验是很明显的,我正在这里寻求一些帮助。

当我用 Java 编写一个多线程应用程序时,我被一个疑问所困扰。请看这个示例代码(混合伪代码和Java):

Thead 1 body(部分)

/* 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... */
        taskCompleted = true;
        notifyAll(); // notify waiting threads
    }

}

我关心的问题很简单:如果语句会发生什么按以下顺序执行:

  1. 线程 1 启动线程 2
  2. 线程 2 执行一些操作,但未完成任务
  3. 线程 1 将 taskCompleted 读取为 false
  4. 线程 2 完成任务,引发 taskCompleted 标志,并通知(无人)
  5. 线程 1 开始等待。并且永远不会结束。

如果您有任何想法和/或这是一个众所周知的场景(完全重复?),请告诉我

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... */
        taskCompleted = 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?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仅此而已 2024-12-10 11:15:06

taskCompleted 标志和 wait()/nofiyAll() 的使用必须受锁保护,以避免出现您所描述的情况。

/* It creates and starts thread Thread 2 */
synchronized (thread2) {
  if (!thread2.taskCompleted)
    thread2.wait();
}
/* continue execution... */

class Thread2 extends Thread {

  boolean taskCompleted = false;

  public void run() {
    /* It executes a complex task... */
    synchronized (this) {
      taskCompleted = true;
      notifyAll(); // notify waiting threads
    }
  }
}

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
    }
  }
}
初吻给了烟 2024-12-10 11:15:06

除了其他人之前回答过的内容之外,根据我个人的经验,尽可能避免使用 wait 、 notification 等(除非您正在构建自定义同步器)。有许多好的且足够的类,如信号量、屏障、闩锁、锁或通用同步。
它们在 90% 的情况下就足够了。
在上面的情况下,您可以使用 synchronized(this) 或与任何其他变量一起使用。
或者可以使用 ReenterantLock

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文