fig*_*aro 6 java multithreading synchronization notify wait
具体来说,有人可以告诉我这段代码有什么问题.它应该启动线程,所以应该打印"输入线程..."5次,然后等到调用notifyAll().但是,它会随机打印"输入......"和"完成......",并且仍在等待其他人.
public class ThreadTest implements Runnable {
private int num;
private static Object obj = new Object();
ThreadTest(int n) {
num=n;
}
@Override
public void run() {
synchronized (obj) {
try {
System.out.println("Entering thread "+num);
obj.wait();
System.out.println("Done Thread "+num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Runnable tc;
Thread t;
for(int i=0;i<5;i++) {
tc = new ThreadTest(i);
t = new Thread(tc);
t.start();
}
synchronized (obj) {
obj.notifyAll();
}
}
}
Run Code Online (Sandbox Code Playgroud)
你没有对方法调用做任何明显的错误,但是你有竞争条件.
虽然在一个理想的世界中,主线程将在所有工作线程到达wait()调用后到达其synchronized块,但无法保证(您明确告诉虚拟机您不希望线程按顺序执行用主线程制作线程).可能会发生(例如,如果您只有一个核心)线程调度程序决定立即阻止所有工作线程,它们开始允许主线程继续.可能由于高速缓存未命中而将工作线程切换出上下文.可能是一个工作线程阻塞I/O(print语句)并且主线程在其位置切换.
因此,如果主线程在所有工作线程到达wait()调用之前设法到达同步块,则那些尚未到达wait()调用的工作线程将无法按预期运行.由于当前设置不允许您控制此操作,因此必须添加对此的显式处理.您可以添加某种变量,当每个工作线程到达wait()并且主线程不调用notifyAll()直到此变量达到5,或者您可以使用主线程循环并重复调用notifyAll()时,会增加某种变量.以便工作线程在多个组中发布.
看一下这个java.util.concurrent包 - 有几个锁类比基本的同步锁提供更强大的功能 - 一如既往,Java可以让您免于重新发明轮子.CountDownLatch似乎特别相关.
总之,并发很难.您必须设计以确保当线程在您不想要的订单中执行时,一切仍然有效,以及您希望的订单.
| 归档时间: |
|
| 查看次数: |
7811 次 |
| 最近记录: |