Я изо всех сил пытаюсь понять порядок, в котором ожидающие потоки выполняются, когда я вызываю notifyAll для определенного объекта. Ниже приведен пример кода, на который я буду ссылаться.
Короче, могу ли я быть уверен, что если у меня есть 100 потоков с именем "AB C" в очереди ожидания и 100 потоков с именем "GHI" "в очереди на вход все потоки" AB C "будут выполняться перед потоками" GHI "?
Когда я запускаю короткую программу, кажется, что это всегда так, поскольку потоки" GHI "всегда выведите «0», что означает, что все потоки «AB C» к тому времени закончили выполнение. Мне просто интересно - это моя система / реализация специфицируется c или я могу быть уверен, что так будет всегда? Из документации Java я не смог найти гарантии по этому поводу, но, возможно, я не нашел нужного места.
Вот краткий пример кода, на который я ссылался и который всегда дает для меня непротиворечивые результаты:
public class Main {
private volatile int count = 0;
public static void main(String[] args) throws InterruptedException {
Main main = new Main();
// add 100 threads that will all go to wait
main.addThreads("ABC");
// wait for 100 threads to be created and then notify all after sleeping 10s
main.waitForThreads();
// make sure thread has managed to start and is holding the lock and slpeeping
Thread.sleep(1000);
// add a lot more consumers to entry queue
main.addThreads("GHI");
//wait for threads to finish
Thread.sleep(15000);
}
private void waitForThreads() throws InterruptedException {
while (this.count < 99) {
System.out.println("Not enough waiting threads yet");
Thread.sleep(1000);
}
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Main.this.syncMethod();
} catch (InterruptedException e) {
}
}
}, "DEF");
t.start();
}
private void addThreads(String threadName) {
for(int i = 0; i < 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Main.this.syncMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
}}, threadName).start();;
}
}
private synchronized void syncMethod() throws InterruptedException {
String name = Thread.currentThread().getName();
if (name.equals("ABC")) {
this.count++;
this.wait();
this.count--;
} else if (name.equals("DEF")) {
Thread.sleep(10000);
this.notifyAll();
System.out.println("Waiting threads notified");
} else {
System.out.println(this.count);
}
}
}