所有。我有一个关于Java等待通知机制的问题。答案是保证线程将按此顺序执行 - 从最后到第一个等等。结果总是100,99,...,1?这是代码片段:
public class Main {
static int counter = 0;
static Object o = new Object();
public static void main(String[] args){
for(int i = 0; i < 100; ++i){
new Thread(() -> {
synchronized (o) {
try {
int c = ++counter;
o.wait();
System.out.println("" + c);
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o) {
new Thread(()-> {
synchronized(o){
System.out.println("LAsttttttttttttttttt");
}
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
o.notifyAll();
}
}
}
我跑了10次,结果总是一样的。我在互联网上找不到任何相关内容。还有一个问题 - 当我们有100个线程在等待时,当我们通知所有时,是否有保证第一个等待线程将被执行,之后是第二个,并且在执行所有100个等待线程之后,其他等待方法(这是在synchronized块中,但在它们的主体中没有wait()),之后将执行(在执行所有100个正在等待的线程之后)。或者notifyAll只保证所有等待的线程都会开始与这个对象同步的每个方法一起战斗?我觉得这就是答案: “唤醒的线程将无法继续直到当前 *线程放弃对此对象的锁定。被唤醒的线程 *将以通常的方式与任何可能的其他线程竞争 *积极竞争同步这个对象;例如, *被唤醒的线程没有可靠的特权或劣势 *是锁定此对象的下一个线程。“
但我想确定我了解当我们等待通知时发生了什么。 提前谢谢。
答案 0 :(得分:3)
不。 。不能保证一组唤醒线程将以任何特定顺序执行。 (这可能是因为JVM的特定实现或运行程序的计算机的速度,或许多其他基于负载的变量而按顺序发生。但是,没有语言保证。)
答案 1 :(得分:2)
Java的同步代码块不保证允许进入同步块的线程进入的顺序,并且notifyAll()
不会将自身作为特殊情况出现。< / p>
正如你在notifyAll()
javadoc(强调我的)中看到的那样:
唤醒的线程将无法继续,直到当前线程放弃对此对象的锁定。 唤醒的线程将以通常的方式与可能在此对象上主动竞争同步的任何其他线程竞争;例如,被唤醒的线程在下一个锁定该对象的线程中没有可靠的特权或劣势。