java - threading - thread sync black squad
¿Cuál es el equivalente de java de ManualResetEvent? (5)
Esta pregunta ya tiene una respuesta aquí:
¿Cuál es el equivalente de java de ManualResetEvent ?
Creo que el quid de la MRE .NET es la afinidad de los hilos y su capacidad para dejar pasar todos los hilos en espera cuando se llama Set. Encontré que el uso del semáforo funciona bien. Sin embargo, si tengo 10 o 15 subprocesos esperando, entonces me encuentro con otro problema. Específicamente, ocurre cuando se llama Set. En .Net, todos los hilos en espera se liberan. Usar un semphore no libera todo. Así que lo envolví en una clase. NOTA: Estoy muy familiarizado con los subprocesos .NET. Soy relativamente nuevo en el subprocesamiento y la sincronización de Java. Sin embargo, estoy dispuesto a participar y obtener una respuesta real. Aquí está mi implementación con suposiciones que un principiante de Java haría:
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));
}
}
También tenga en cuenta que básicamente estoy apostando a que no hay más de 1000 solicitudes esperando un lanzamiento en un momento dado. Al liberar y adquirir en lotes, estoy intentando liberar cualquier subproceso en espera. Tenga en cuenta que la llamada a WaitOne está funcionando 1 permiso a la vez.
Intente CountDownLatch con la cuenta de uno.
CountDownLatch startSignal = new CountDownLatch(1);
Residencia en:
ManualResetEvent permite que los hilos se comuniquen entre sí mediante señalización. Normalmente, esta comunicación se refiere a una tarea que un subproceso debe completar antes de que puedan continuar otros subprocesos.
de aquí:
es posible que desee ver las barreras en el paquete de concurrencia de Java, específicamente CyclicBarrier , creo:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CyclicBarrier.html
Bloquea un número fijo de subprocesos hasta que se produce un evento en particular. Todos los hilos deben unirse en un punto de barrera .
Lo más cercano que conozco es el Semaphore . Solo úselo con un recuento de "permisos" de 1, y aquire / release será prácticamente igual a lo que sabe de ManualResetEvent
.
Un semáforo inicializado a uno, y que se utiliza de manera que solo tenga como máximo un permiso disponible, puede servir como un bloqueo de exclusión mutua. Esto se conoce más comúnmente como un semáforo binario, porque solo tiene dos estados: un permiso disponible o cero permisos disponibles. Cuando se usa de esta manera, el semáforo binario tiene la propiedad (a diferencia de muchas implementaciones de bloqueo), que el "bloqueo" puede ser liberado por un subproceso distinto del propietario (ya que los semáforos no tienen noción de propiedad). Esto puede ser útil en algunos contextos especializados, como la recuperación de interbloqueos.
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;
}
}