Я использую LinkedBlockingQueue для обработки объектов сообщений из других потоков. Например, у меня есть что-то вроде этого:Java: synchronized put() со списком объектов
LinkedBlockingQueue<Message> message_queue = new LinkedBlockingQueue<Message>();
public void run(){
while(true){
Message m = message_queue.take();
handle_message(m);
}
}
При добавлении нового сообщения из другого потока, я называю message_queue.put (м). Нет проблем! Мой вопрос таков:
Как синхронизировать добавление набора сообщений одновременно? Скажем, я хочу сделать это:
Message[] messages = {/* some list of message objects */};
for (Message m : messages){
message_queue.put(m);
}
Проблема заключается в том, что другой поток может делать то же самое, и сообщения из одного потока не гарантируется быть поставлено в очередь точно так, как я намерен. Сообщения из конкурирующей нити могут быть «перемежены» между ними (т. Е. Фактическая последовательность может в конечном итоге быть A, A, B, B, A, B вместо предполагаемых A, A, A, B, B, B) Я знаю, что я может помещать цикл в пример «put» в «синхронизированный (message_queue) {}» блок, но мне также нужно будет поместить тот же самый блок вокруг вызова .take()? И, очевидно, я не могу этого сделать, так как это мгновенно создаст тупиковую ситуацию, так как take() блокирует до тех пор, пока не будет добавлено новое сообщение(), чего не может произойти, если блокируется синхронизацией. Могу ли я пропустить синхронизированный блок при вызове take(), имея только синхронизированный блок в цикле put и получить желаемый эффект? Благодаря!
согласился: единственная проблема с заказом: 2 операции массового ввода сталкиваются друг с другом или с одной транзакцией. –