Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > 2 параллельных Thread wait()/notify()


Автор: AbdulBcex 26.7.2010, 11:50
Здраствуйте!

Тут такое дело. Есть код.
Код

while(isActive){

//Первая очередь
   synchronized(inputQueue){
    try {
        inputQueue.wait(10,1);
    } catch (InterruptedException e) {}                        
    }            
if(!inputQueue.isEmpty()){ 
    while(!inputQueue.isEmpty()){
      processingQueue();
   }}
//Вторая очередь                
    synchronized(inputQueue2){                        
    try {
          inputQueue2.wait(10,1);
    } catch (InterruptedException e) {}                
        }
if(!inputQueue2.isEmpty()){ 
                
    while(!inputQueue2.isEmpty()){
    processQueue2();
    }}}


Как (надеюсь smile ) видно, поток (а это именно Thread) пока active ждет 10ms+1ns одной очереди (если есть данные - обрабатывает их), потом переключается на другую... И так постоянно. Это вообще нормальная ситуация, так потоки гонять? Для быстродействия, надежности, например? Подскажите, а есть ли способ описать все это красивее, то есть, чтобы поток ждал одновременно notify() от обеих очередей и выполнял processing именно той очереди, которая отозвалась раньше. Чего-то я такого не нашел. Вероятность одновременного "отзыва" обеих очередей сведена к минимуму.

Автор: x8m6 26.7.2010, 12:58
А почему бы вам не сделать так, чтобы каждый поток обрабатывал свою очередь? 2-очереди -> 2 потока. Ну или можно сделать пул потоков на каждую очередь.

Автор: AbdulBcex 26.7.2010, 14:41
Ну, во-первых, не позволяет особо уже написанный код. Во-вторых, таких объектов, с потоками может в теории быть очень много, что, думается, несомненно отразится на общей производительности. Сейчас их 3, а может быть пара десятков - то есть в районе 40 потоков. К тому же это не единственные потоки в программеsmile.

Автор: AbdulBcex 27.8.2010, 17:32
Цитата

А почему бы вам не сделать так, чтобы каждый поток обрабатывал свою очередь? 2-очереди -> 2 потока. Ну или можно сделать пул потоков на каждую очередь.

Так и сделал в итоге.
Код

public class Operator2 implements Runnable{
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
...
//который запускает две задачи у объекта 
run{
scheduler.schedule(inputQueueProcessor, 100, TimeUnit.NANOSECONDS);
scheduler.schedule(inputQueue2Processor, 150, TimeUnit.NANOSECONDS);
...
}}

Задачи - это те, что в первом моем посте после комментариев (подождал, обработал), только разбиты соответственно на две Runnable для scheduler. Основное изменение - inputQueue(2).wait(0) теперь (побольшей части) имеют в качестве временного параметра 0 - то есть ждут до отклика. Оказалось, что так лучше в плане производительности, чем гонять их постоянно в цикле.
Фишка в том, что у объекта Operator2 все же может возникнуть такая ситуация, когда inputQueueProcessor должен будет ждать с параметром 0, а inputQueueProcessor2 не будет тратить время, подождет 1ms например и пойдет дальше. Или наоборот, или обе сразу. На практике выходит, что второй поток в итоге будет ждать, пока закончит первый и вся "параллельность" на смарку.  

Подскажите, пожалуйста, что тут можно сделать? Как сделать так, что бы они действительно независимо друг от друга работали? Не соображу никак...  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)