Подтвердить что ты не робот

Что такое Java-эквивалент ManualResetEvent?

Что такое java-эквивалент ManualResetEvent?

4b9b3361

Ответ 1

Ближайшим, о котором я знаю, является Semaphore. Просто используйте его с графом "разрешение" 1, а aquire/release будет почти таким же, как то, что вы знаете из ManualResetEvent.

Семафор, инициализированный одним, и который используется так, что он имеет доступно только одно разрешение, может служить как блокировка взаимного исключения. Это более известный как двоичный семафор, потому что он имеет только два заявляет: доступно одно разрешение или ноль Разрешения доступны. При использовании в этом путь, двоичный семафор имеет свойство (в отличие от многих Lock реализации), что "блокировка" может быть выпущена нитью, отличной от (поскольку семафоры не имеют понятия владение). Это может быть полезно в некоторых специализированные контексты, такие как взаимоблокировка восстановления.

Ответ 2

class ManualResetEvent {

  private final Object monitor = new Object();
  private volatile boolean open = false;

  public ManualResetEvent(boolean open) {
    this.open = open;
  }

  public void waitOne() throws InterruptedException {
    synchronized (monitor) {
      while (open==false) {
          monitor.wait();
      }
    }
  }

  public boolean waitOne(long milliseconds) throws InterruptedException {
    synchronized (monitor) {
      if (open) 
        return true;
      monitor.wait(milliseconds);
        return open;
    }
  }

  public void set() {//open start
    synchronized (monitor) {
      open = true;
      monitor.notifyAll();
    }
  }

  public void reset() {//close stop
    open = false;
  }
}

Ответ 3

Попробуйте CountDownLatch со счетом 1.

CountDownLatch startSignal = new CountDownLatch(1);

Ответ 4

На основании:

ManualResetEvent позволяет потокам взаимодействовать друг с другом посредством сигнализации. Как правило, это связь связана с задачей, которая один поток должен завершиться перед другим потоки могут продолжаться.

отсюда:

http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx

вы, возможно, захотите посмотреть на барьеры в пакете Java concurrency - особенно CyclicBarrier. Я полагаю:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CyclicBarrier.html

Он блокирует фиксированное количество потоков до тех пор, пока не произойдет определенное событие. Все нити должны объединяться в барьерную точку.

Ответ 5

Я считаю, что суть .NET MRE связана с потоком и его способностью пропускать все ожидающие потоки при вызове Set. Я нашел, что использование Семафора хорошо работает. Однако, если я получаю 10 или 15 потоков, ожидающих, тогда я сталкиваюсь с другой проблемой. В частности, это происходит, когда вызывается Set. В .Net все ожидающие потоки освобождаются. Использование semphore не освобождает все. Поэтому я завернул его в класс. ПРИМЕЧАНИЕ. Я очень хорошо знаком с потоками .NET. Я относительно новичок в потоке и синхронизации Java. Тем не менее, я готов вскочить и получить реальную обратную связь. Здесь моя реализация с предположениями, которые начинал Java-начинающий:

public class ManualEvent {
private final static int MAX_WAIT = 1000;
private final static String TAG = "ManualEvent"; 
private Semaphore semaphore = new Semaphore(MAX_WAIT, false);

private volatile boolean signaled = false;
public ManualEvent(boolean signaled) {
    this.signaled = signaled; 
    if (!signaled) {
        semaphore.drainPermits();
    }
}

public boolean WaitOne() {
    return WaitOne(Long.MAX_VALUE);
}

private volatile int count = 0;
public boolean WaitOne(long millis) {
    boolean bRc = true;
    if (signaled)
        return true;

    try {
        ++count;
        if (count > MAX_WAIT) {
            Log.w(TAG, "More requests than waits: " + String.valueOf(count));
        }

        Log.d(TAG, "ManualEvent WaitOne Entered");
        bRc = semaphore.tryAcquire(millis, TimeUnit.MILLISECONDS);
        Log.d(TAG, "ManualEvent WaitOne=" + String.valueOf(bRc));
    }
    catch (InterruptedException e) {
        bRc = false;
    }
    finally {
        --count;
    }

    Log.d(TAG, "ManualEvent WaitOne Exit");
    return bRc;
}

public void Set() {
    Log.d(TAG, "ManualEvent Set");
    signaled = true;
    semaphore.release(MAX_WAIT);
}

public void Reset() {
    signaled = false;
    //stop any new requests
    int count = semaphore.drainPermits();
    Log.d(TAG, "ManualEvent Reset: Permits drained=" + String.valueOf(count));
}

}

Также обратите внимание, что я в основном делаю ставку на то, что не более 1000 запросов, ожидающих выхода в любой момент времени. Выпуская и реализуя партии, я пытаюсь выпустить любые ожидающие потоки. Обратите внимание, что вызов WaitOne работает по 1 разрешению за раз.