什么是java相当于ManualResetEvent?
答案 0 :(得分:27)
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;
}
}
答案 1 :(得分:19)
我最接近的是Semaphore。只需使用“许可”计数为1,而获取/发布将与您在ManualResetEvent
中所知的几乎相同。
信号量初始化为1,和 这是使用它只有在 大多数可用的许可证,可以服务 作为互斥锁。这是 通常称为二进制 信号量,因为它只有两个 州:一个许可证可用,或零 许可证。在此使用时 方式,二进制信号量有 财产(不像很多锁 实现),“锁”可以 由除以外的线程释放 所有者(因为信号量没有概念 所有权)。这在一些人中很有用 专门的上下文,例如死锁 回收
答案 2 :(得分:8)
尝试CountDownLatch,数量为一。
CountDownLatch startSignal = new CountDownLatch(1);
答案 3 :(得分:3)
基于:
ManualResetEvent允许线程通过相互通信 信号。通常,这 沟通涉及一项任务 一个线程必须先完成其他线程 线程可以继续。
从这里开始:
http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx
你可能想看看Java并发包中的障碍 - 特别是 CyclicBarrier 我相信:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CyclicBarrier.html
它会阻止固定数量的线程,直到发生特定事件。所有线程必须在屏障点汇集在一起。
答案 4 :(得分:2)
我相信.NET MRE的关键在于线程亲和性以及它在调用Set时允许所有等待线程通过的能力。我发现Semaphore的使用效果很好。但是,如果我等待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个。