Что такое java-эквивалент ManualResetEvent?
Что такое Java-эквивалент ManualResetEvent?
Ответ 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 разрешению за раз.