Я не знаю, возможна ли эта ситуация или нет, и я не знаю, что мне делать для достижения моих потребностей. У меня есть класс под названием A. В классе AI есть 02 методов (m1 и m2) и поток 01. Поток будет отвечать за прослушивание соединения сокета для любого входящего сообщения. Если сообщение поступит, поток вызовет метод m1 для обработки сообщения. Поток запускается, когда класс инициализируется.
Тогда у меня есть метод m2, который отвечает за отправку сообщения в сокет (тот же сокет, который прослушивает поток). Каждый раз, когда метод m2 отправляет сообщение в сокет, в нем будет ответное сообщение. Я не реализовал этот код как прослушивание сокета сразу после отправки сообщения, потому что сокет иногда может отправлять случайные сообщения.
Мой вопрос в том, есть ли какой-либо возможный способ, когда мой метод m2 отправляет сообщение, он будет ждать завершения метода m1 (вызванного потоком) до выхода?
Большое спасибо.
Для этого вы можете использовать методы wait/notify. В качестве блокировки вам понадобится какой-то взаимный объект. Ознакомьтесь с https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html для получения дополнительной информации об этом.
Lock
: P
Это типичная ситуация с потребителем-производителем. Поток один обрабатывает получение данных (производить), а поток два обрабатывает обработку этих данных (потребляет). Я не уверен, как вы передаете данные между вашими потоками, но это должно быть сделано с какой-то синхронизированной конструкцией. Вот пример того, как это сделать с помощью BlockingQueue, который избегает любой причины для реализации блокировок или условных переменных напрямую
//Shared Queue
BlockingQueue<Data> queue = new LinkedBlockingQueue<Data>();
Вставить один (получение)
//get Data object d here
queue.put(d);
Предполагая, что вы не указали ограничение для очереди, это не будет блокироваться (если ваша очередь не queue.size() == Integer.MAX_VALUE
)
Тема 2 (процесс)
Data d = queue.take(); //this will block indefinitely until there is data available
//process data here
Поскольку BlockingQueue
имеет встроенные в него блокировки и переменные условия, вам не нужно вручную обрабатывать их. Блокировка по существу такая же, как вызов await()
(аналогично object.wait()
), и когда есть данные, вызывается signal()
(похожий на object.notify()
). Это был бы самый простой способ выполнить то, что вы запрашиваете, без обработки самой синхронизации. Он также позволяет устанавливать таймауты в случае, если вы не хотите блокировать навсегда.
Condition
. Это может быть просто из-за моего прошлого, когда я впервые научился делать это с библиотекой pthreads в C / C ++.