Причина проблемы: несинхронизированное чтение и запись из очереди и в очередь.
Здесь происходит то, что оба потока, работающие на разных ядрах ЦП, работают со своей собственной копией очереди,таким образом, производитель может добавлять материал, и эти изменения, вероятно, даже распространяются в ОЗУ, но потребитель никогда ничего не проверяет в ОЗУ, поскольку у него есть собственная кэшированная копия этой очереди, ведьма остается пустой.
Thread.sleep()
все работает, потому что при пробуждении поток должен получить все данные из ОЗУ, где он, вероятно, изменился.
Правильный способ сделать это - получить доступ к очереди только при синхронизации по ней какследует:
у производителя:
synchronized(Manager.queue) {
Manager.queue.add(new Job());
}
и у потребителя:
boolean continue = true;
while (continue) {
synchronized(Manager.queue) {
Job job=Manager.queue.pop();
}
}
И, наконец, последний штрих: while (true)
- все невероятно неэффективно, выможет сделать что-нибудь, используя Object.wait()
и Object.notify()
В производителе:
synchronized(Manager.queue) {
Manager.queue.add(new Job());
Manager.queue.notify();
}
и в Потребителе:
boolean continue = true;
while (continue) {
synchronized(Manager.queue) {
while (Manager.queue.peek() == null) {
Manager.queue.wait();
}
Job job=Manager.queue.pop();
}
}