为什么通常线程样本会在synchronized块中放入如此多的代码。根据我的理解,在以下情况中,synchronized仅用于锁定b等待并通知:
主类ThreadA:
class ThreadA {
public static void main(String [] args) {
ThreadB b = new ThreadB();
b.start();
synchronized(b) {
try {
System.out.println("Waiting for b to complete...");
b.wait();
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.total);
System.out.println(Thread.currentThread().getName());
}
}
}
和类ThreadB:
class ThreadB extends Thread {
int total;
public void run() {
synchronized(this)
{
System.out.println();
for(int i=0;i<100;i++)
{
System.out.println(Thread.currentThread().getName());
total += i;
}
notify();
}
}
}
如果我只在wait
块中添加notify
和synchronized
,会有什么变化:
class ThreadA {
public static void main(String [] args) {
ThreadB b = new ThreadB();
b.start();
try {
System.out.println("Waiting for b to complete...");
synchronized(b) { b.wait();}
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.total);
System.out.println(Thread.currentThread().getName());
}
}
答案 0 :(得分:3)
根据我的理解,在以下情况中,synchronized仅用于锁定b等待并通知
你的理解是错误的。
synchronized
也用于:
如果我只是在同步块中等待并通知,那么会发生什么变化:
在这种特殊情况下,它将根据竞争条件产生差异 - 在原始代码中,如果新的thread
在之前开始执行,则在原始代码中达到同步块线程,它将不会达到“等待b完成”,直到第二个线程完成...此时它将永远阻塞wait
。
请注意,在Thread
监视器上等待非常糟糕,因为wait/notify
在内部使用Thread
。
简而言之,您使用的示例以各种方式开始时很糟糕 - 但同步 不仅仅用于wait/notify
。
答案 1 :(得分:0)
请注意,total += i
不是Java中的原子操作。所以你必须同步这个结构。
您还必须同步notify()和wait(),因为它们的锁是在内部处理的。