是否可能出现这样的竞争条件等待线程完成任务?
我对并发的缺乏经验是很明显的,我正在这里寻求一些帮助。
当我用 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 启动线程 2
- 线程 2 执行一些操作,但未完成任务
- 线程 1 将 taskCompleted 读取为 false
- 线程 2 完成任务,引发 taskCompleted 标志,并通知(无人)
- 线程 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:
- 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?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
taskCompleted
标志和wait()/nofiyAll()
的使用必须受锁保护,以避免出现您所描述的情况。和
The usage of the
taskCompleted
flag andwait()/nofiyAll()
must be protected by a lock to avoid the scenario you describe.and
我认为这些块应该同步,请参阅http://download.oracle。 com/javase/tutorial/essential/concurrency/guardmeth.html。
或者您可以使用类似 CountDownLatch 的内容,请参阅: http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html
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
除了其他人之前回答过的内容之外,根据我个人的经验,尽可能避免使用 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