2016-10-11 13 views
1

Очень упрощенная версия моего проекта. Несколько экземпляров MyThread попытаются получить и удалить одну форму элемента Set, определенную в классе MyWorker, и выполните некоторую работу с ним.Заблокировать нить, пока ресурс пуст

В остальном мой код (не вклеен здесь) У меня есть хотя бы один поток, который заполняется Set в MyWorker, поэтому нет никакого риска, что ParseNextPendingElement() никогда не найдет элемент в Set.

Моя проблема в том, что я не знаю, как «заблокировать» поток на пустом множестве. Теперь я выполнил примитивную задержку после неудачного доступа к Set. Как я могу добиться ожиданий, когда Set будет иметь хотя бы один элемент, а не напрягать процессор во время ожидания?

public class MyThread implements Runnable { 
    private MyWorker worker; 

    //constructors, get, set, etc. 

    public void run() { 
     worker.ParseNextPendingElement(); 
    } 
} 

private static class MyWorker { 
    private Set set; 

    //constructors, get, set, etc. 

    public void ParseNextPendingElement() { 
     Object elemToParse; 

     while(1) { 
      synchronized(set) { 
       if(!set.isEmpty()) { 
        elemToParse = set.remove(); 
        break; 
       } 
      } 

      // BRUTAL workaround to not stress CPU while waiting for 
      // at least one element in set. 
      Thread.delay(100); 
     } 

     // Do some stuff with elemToParse 
     return; 
    } 
} 

ответ

3

Если вы хотите иметь поведение потоков, которые будут входить в состоянии ожидания и вернутся, когда у вас есть новый вход, это звучит как работа для LinkedBlockingQueue из java.util.concurrent пакета вместо просто набора.

LinkedBlockingQueue имеет способ take(), который будет вводить поток в состояние ожидания, если очередь пуста, и вернется, когда в ней будут новые элементы.

 Смежные вопросы

  • Нет связанных вопросов^_^