Поток Java как поток цикла событий

#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 . Это должно дать вам все, что вам нужно, и многое другое