Я новичок в концепции BlockingQueue, и у меня создалось впечатление, что потребовалось wait() и notify(). Я написал следующий код в качестве предварительного теста синхронизации потоков (исключая код для ясности):Синхронизация нити с BlockingQueue в Java
q = new LinkedBlockingQueue<flight>();
generator = new EventGenerator(q,flight);
southwest = new Airline(q);
new Thread(generator).start();
new Thread(southwest).start();
С классом производителя EventGenerator. EventGenerator берет рейс из своего первоначального состояния (SC) через все состояния, пока она не достигнет ворот, AG:
import java.util.concurrent.BlockingQueue;
public class EventGenerator implements Runnable
{
private final BlockingQueue<flight> bqueue;
private final flight f;
EventGenerator(BlockingQueue<flight> q, flight f1)
{
bqueue = q;
f = f1;
}
public void run()
{
try
{
while (f.state != "AG") { bqueue.put(produce()); }
}
catch (InterruptedException ex)
{
System.out.println(ex);
System.exit(0);
}
}
flight produce()
{
if (f.state.equals("SC")){ f.state = "BD"; }
else if (f.state.equals("BD")) { f.state = "LG"; }
else if (f.state.equals("LG")) { f.state = "TO"; }
else if (f.state.equals("TO")) { f.state = "LD"; }
else if (f.state.equals("LD")) { f.state = "AG"; }
return f;
}
Потребительский класс Авиакомпания получить каждое изменение в состоянии полета, и распечатать его :
import java.util.concurrent.BlockingQueue;
public class Airline implements Runnable
{
private final BlockingQueue<flight> bqueue;
Airline(BlockingQueue<flight> q)
{
bqueue = q;
}
public void run()
{
try
{
while (!bqueue.isEmpty()) { consume(bqueue.take());}
}
catch (InterruptedException ex)
{
System.out.println(ex);
System.exit(0);
}
}
void consume(flight f)
{
System.out.println("Flight no. " + f.flightno + " is now in state " + f.state);
}
}
Проект компилируется и запускается без ошибок. Тем не менее, я ожидал (и хотят) результат будет что-то на мотив:
Flight no. 1 is now in state SC
Flight no. 1 is now in state BD
Flight no. 1 is now in state LG
Flight no. 1 is now in state TO
Flight no. 1 is now in state LD
Flight no. 1 is now in state AG
Но вместо этого, я почти всегда получаю:
Flight no. 1 is now in state AG
Flight no. 1 is now in state AG
Flight no. 1 is now in state AG
Flight no. 1 is now in state AG
Flight no. 1 is now in state AG
ли я реализовал BlockingQueue неправильно?
A) не используйте буквы нижнего регистра для имен классов. B) вы никогда не инициализируете 'полет' в любом месте - этот код будет вызывать NPE. C) Вы используете '! =' Для сравнения строк в цикле while, который является причиной вывода. –
A) Я не мог понять, как отредактировать мою опечатку в Eclipse, это не позволит мне изменить ее, не изменяя имя файла. B) Я пропустил это, потому что инициализация является длинной. C) Верно, спасибо. – aquemini
Чтобы переименовать свой класс (и его файл) в Eclipse, щелкните правой кнопкой мыши, Refactor-> Rename. – Perception