#java #multithreading #qthread #event-loop
#java #многопоточность #qthread #цикл событий
Вопрос:
Я хочу использовать поток в качестве потока цикла событий. Я имею в виду поток Java с «поведением, подобным QThread» ( t2
в следующем примере). Объяснение:
У меня есть поток t1
(основной поток) и поток t2
(рабочий поток). Я хочу, чтобы это method()
, вызываемое из t1
, выполнялось в t2
потоке.
В настоящее время я создал этот код (он работает, но мне это не нравится):
-Поток t1 (например, основной поток, поток пользовательского интерфейса):
//...
// Here, I want to call "method()" in t2's thread
Runnable event = new Runnable() {
@Override
public void run()
{
t2.method(param);
}
};
t2.postEvent(event);
//...
-Поток t2:
//...
Queue<Runnable> eventLoopQueue = new ConcurrentLinkedQueue<Runnable>();
//...
@Override
public void run()
{
//...
Runnable currentEvent = null;
while (!bMustStop) {
while ((currentEvent = eventLoopQueue.poll()) != null) {
currentEvent.run();
}
}
//...
}
public void method(Param param)
{
/* code that should be executed in t2's thread */
}
public void postEvent(Runnable event)
{
eventLoopQueue.offer(event);
}
Это решение уродливо. Мне не нравится «всегда работающий» основной цикл t2
, Runnable
каждый раз новое выделение t1
… Моя программа может вызывать method
что-то вроде 40 раз в секунду, поэтому мне нужно, чтобы она была эффективной.
Я ищу решение, которое также следует использовать на Android (я знаю class Looper для Android, но это только для Android, поэтому невозможно)
Ответ №1:
Рассмотрите возможность использования BlockingQueue
вместо Queue
для его метода take()
, который заблокирует поток до тех пор, пока элемент не будет доступен в очереди, что позволит не тратить циклы, как poll()
это происходит.
Ответ №2:
Вы также можете синхронизировать (используя synchronized / wait / notify ), чтобы дождаться публикации нового четного. Но, как упоминалось в предыдущем ответе, BlockingQueue может выполнить эту работу. Только не забудьте прервать, когда вы планируете выйти из потока (в обоих случаях).
Ответ №3:
Начиная с Java 1.5, существует отличное готовое решение для объединения потоков. У вас есть пул потоков, в который вы можете отправить задачу на выполнение. Пул принимает поток и выполняет вашу задачу. После выполнения задачи поток прозрачно возвращается в пул. Пожалуйста, посмотрите на интерфейс ExecutorService и все его реализации. Также взгляните на вспомогательный класс Executors . Это должно дать вам все, что вам нужно, и многое другое