【发布时间】:2019-05-09 14:06:08
【问题描述】:
我在课堂上有一个同步方法。 try 子句中的代码调用notifyAll() 和wait()。当我运行代码时,所有线程都根据输出运行。但事实证明只有两个线程依次调用该方法。太可怕了。
我尝试在非同步方法的 while 循环中编写同步块,并且效果很好。请注意,总共有 5 个线程。
这里是同步方法:
private synchronized void sell() {
while (ticketsLeft > 0) {
try {
System.out.println(Thread.currentThread().getName() + "__________" + (ticketsLeft--));
this.notifyAll();
Thread.sleep(10);
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(0);
}
我也尝试将while循环放在同步块中,同样的事情发生了。
private void sell() {
synchronized (this) {
while (ticketsLeft > 0) {
try {
System.out.println(Thread.currentThread().getName() + "__________" + (ticketsLeft--));
this.notifyAll();
Thread.sleep(10);
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(0);
}
}
而且是这样工作的,线程 3 和 4 依次调用该方法:
5__________100
1__________99
2__________98
3__________97
4__________96
3__________95
4__________94
3__________93
4__________92
3__________91
4__________90
3__________89
4__________88
3__________87
4__________86
3__________85
4__________84
3__________83
4__________82
3__________81
4__________80
在非同步方法内的while循环中使用同步块:
private void sell() {
while (ticketsLeft > 0) {
try {
synchronized (this) {
System.out.println(Thread.currentThread().getName() + "__________" + (ticketsLeft--));
this.notifyAll();
Thread.sleep(10);
this.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(0);
}
它按我的预期工作:
5__________100
3__________99
2__________98
1__________97
4__________96
1__________95
2__________94
3__________93
1__________92
4__________91
3__________90
2__________89
5__________88
2__________87
3__________86
4__________85
1__________84
3__________83
2__________82
5__________81
3__________80
感谢大家阅读这个问题。很抱歉,我没有足够的声誉来发布图片。如果有人对此有想法,我将不胜感激。
【问题讨论】:
-
因为任何线程碰巧在它们都被唤醒后首先尝试获取同步锁都会获得同步锁,并且很有可能根据您的特定配置,它是前两个。如果您希望资源与所有线程公平共享,请使用一种公平平衡的机制。这根本不是同步的重点,相反,同步试图成为最有效的,远非最公平的。
标签: java multithreading synchronized