The closest I know of is the Semaphore. Just use it with a "permit" count of 1, and aquire/release will be pretty much the same as what you know from the ManualResetEvent.
A semaphore initialized to one, and
which is used such that it only has at
most one permit available, can serve
as a mutual exclusion lock. This is
more commonly known as a binary
semaphore, because it only has two
states: one permit available, or zero
permits available. When used in this
way, the binary semaphore has the
property (unlike many Lock
implementations), that the "lock" can
be released by a thread other than the
owner (as semaphores have no notion of
ownership). This can be useful in some
specialized contexts, such as deadlock
recovery.
ManualResetEvent allows threads to communicate with each other by
signaling. Typically, this
communication concerns a task which
one thread must complete before other
threads can proceed.
I believe the crux of the .NET MRE is thread affinity and its ability to let all waiting threads go through when Set is called. I found the use of the Semaphore works well. However, if I get 10 or 15 threads waiting, then I run into another issue. Specifically, it occurs when Set is called. In .Net, all waiting threads are released. Using a semphore does not release all. So I wrapped it in a class. NOTE: I am very familiar with .NET threading. I am relatively new to Java threading and synchronization. Nevertheless, I am willing to jump in and get some real feedback. Here's my implementation with assumptions that a Java novice would make:
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));
}
}
Also note that I am basically betting that there's no more than a 1000 requests waiting for a release at any given time. By releasing and aquiring in batches, I am attempting to release any waiting threads. Note the call to WaitOne is working 1 permit at a time.
The closest I know of is the Semaphore. Just use it with a "permit" count of 1, and aquire/release will be pretty much the same as what you know from the
ManualResetEvent
.Based on:
from here:
http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx
you possibly want to look at the Barriers in the Java concurrency package - specifically CyclicBarrier I believe:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CyclicBarrier.html
It blocks a fixed number of threads until a particular event has occured. All the threads must come together at a barrier point.
I believe the crux of the .NET MRE is thread affinity and its ability to let all waiting threads go through when Set is called. I found the use of the Semaphore works well. However, if I get 10 or 15 threads waiting, then I run into another issue. Specifically, it occurs when Set is called. In .Net, all waiting threads are released. Using a semphore does not release all. So I wrapped it in a class. NOTE: I am very familiar with .NET threading. I am relatively new to Java threading and synchronization. Nevertheless, I am willing to jump in and get some real feedback. Here's my implementation with assumptions that a Java novice would make:
}
Also note that I am basically betting that there's no more than a 1000 requests waiting for a release at any given time. By releasing and aquiring in batches, I am attempting to release any waiting threads. Note the call to WaitOne is working 1 permit at a time.
Try CountDownLatch with count of one.