synchronized(q){
while(!(in.equals("quit"))){
// System.out.println(q.isEmpty());
q.enqueue(in);
in = k.next();
if(in.equals("quit"))
System.exit(0);
}
}
Этот синхронизированный блок слишком большой. Как правило, вы хотите синхронизировать как можно быстрее. Получить и выйти. Чем дольше вы синхронизируете, тем дольше другие потоки блокируются.
Выполнение пользовательского ввода во время синхронизации - нет-нет. Другие потоки не должны быть заблокированы, потому что медленный тип пользователя.
Хуже того, у вас есть весь цикл программы внутри синхронизированного блока. Плохой читатель! Так жадно. Он не снимает блокировку q
, пока пользователь не введет все свои данные и не наберет "выйти". Только тогда он снимает блокировку и позволяет автору продолжить.
while(!(in.equals("quit"))){
// System.out.println(q.isEmpty());
synchronized(q){
q.enqueue(in);
}
in = k.next();
if(in.equals("quit"))
System.exit(0);
}
Автор имеет другой фатальный недостаток. Как только очередь пуста, она выходит. Очередь будет пустовать много времени, правда? Когда это - писатель не должен просто умереть.
Быстрое решение состоит в том, чтобы обернуть все это в бесконечный цикл:
public void run(){
while (true) {
synchronized(q){
while(!q.isEmpty()){
String out = q.dequeue();
System.out.println(out);
}
}
}
}
Это поддержит писателя в живых. Но это также потребляет процессорное время, зацикливаясь миллионы раз, пока этот проклятый пользователь медленно клюет на клавиатуру. Если вы проверите системный монитор, вы увидите, что программа загружена на 100%. Не отлично.
Исправление этой проблемы немного выходит за рамки этого вопроса и ответов. Короткий ответ - использовать wait () и notify () , чтобы разрешить автору спать до тех пор, пока что-нибудь не будет доступно.