2010-11-04 4 views
6

Я ищу неперегружаемый флаг или класс событий в классах параллелизма java, что я могу использовать для проверки того, что что-то сделано и является потокобезопасным. В идеале:java concurrency: flag/event

public interface Event 
{ 
    /** returns true if signal() has been called */ 
    public boolean hasOccurred(); 
    /** returns when signal() has been called */ 
    public void await(); 
    public void signal();   
} 

Что-то вроде этого уже существует? У меня судорога мозга, пытаясь вспомнить

ответ

14

Я думаю, что вы ищете CountDownLatch - в частности, создать его экземпляр с отсчетом 1.

Тогда ваши операции следующим образом:

  • hasOccurred: latch.getCount() == 0
  • ждут: latch.await()
  • сигнала: latch.countDown()

Если вы хотите что-то вы можете сбросить и использовать повторяемость, то CyclicBarrier может быть больше, что вы ищете. CountDownLatches после их запуска не может быть сброшен.

Редактировать: Стоит отметить, что CountDownLatch легче скомпонован для более крупной операции, чем упомянутый интерфейс Event. Так, например, если вы собираетесь дождаться 4 рабочих потоков, чтобы закончить, вы можете может дать каждому работнику собственное событие/1-счет-защелку и ждать каждого по очереди. Тем не менее, проще всего создать единый CountDownLatch со счетом 4 и поделиться этим между всеми рабочими (что совсем не требует никаких изменений в рабочей логике, и это невозможно сделать просто с несколькими меньшими событиями).

+0

ах: спасибо, что работает! +1. –

1

Возможно, вы имели в виду Condition?

class BoundedBuffer { 
    final Lock lock = new ReentrantLock(); 
    final Condition notFull = lock.newCondition(); 
    final Condition notEmpty = lock.newCondition(); 

    final Object[] items = new Object[100]; 
    int putptr, takeptr, count; 

    public void put(Object x) throws InterruptedException { 
    lock.lock(); 
    try { 
     while (count == items.length) 
     notFull.await(); 
     items[putptr] = x; 
     if (++putptr == items.length) putptr = 0; 
     ++count; 
     notEmpty.signal(); 
    } finally { 
     lock.unlock(); 
    } 
    } 

    public Object take() throws InterruptedException { 
    lock.lock(); 
    try { 
     while (count == 0) 
     notEmpty.await(); 
     Object x = items[takeptr]; 
     if (++takeptr == items.length) takeptr = 0; 
     --count; 
     notFull.signal(); 
     return x; 
    } finally { 
     lock.unlock(); 
    } 
    } 
}