我有这段代码:
Profile a = randomProfile();
Thread workerA = new Thread(new Downloader(a));
workerA.start();
Profile b = randomProfile();
Thread workerB = new Thread(new Downloader(b));
workerB.start();
synchronized (workerA) {
try {
workerA.wait();
} catch (InterruptedException e) {
System.out.println("Error on background thread!");
System.exit(1);
}
}
synchronized (workerB) {
try {
workerB.wait();
} catch (InterruptedException e) {
System.out.println("Error on background thread!");
System.exit(1);
}
}
实现Downloader
接口的Runnable
类及其run()
方法如下所示:
@Override
public void run() {
synchronized (this) {
//work...
notify();
}
}
现在,这有时是有意的。大多数情况下,它似乎陷入第二个同步块(它总是通过第一个)。
我做错了吗?
我也有一些概念错误,例如:这个实现没有给我任何优势超过一个线程?
答案 0 :(得分:2)
在wait()
个对象上调用Thread
,但在notify()
个对象上调用Downloader
。
因此后台线程应该没有问题地运行(虽然完全不同步),并且主线程应该总是在第一个synchronized
块中阻塞到无穷大,因为没有人将其唤醒。
这个案例很特别的地方是你在wait()
对象本身上调用了Thread
,这是不鼓励的(而且我的意思是:禁止)。当一个线程终止时,它会自己调用notifyAll()
,所以当workerA
完成后,你就会离开第一个synchronized
块。但到达第二个synchronized
块时,workerB
已经完成,因此第二个wait()
将永远不会结束。
是否存在概念错误取决于您尝试实现的目标。从代码看起来非常像你试图做的是join()
后台线程。