本文介绍了Java相当于.Net的AutoResetEvent?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我应该使用什么来获取语义等同于在Java?
(请参阅)。
What should I use to get semantics equivalent to AutoResetEvent in Java?(See this question for ManualResetEvent).
推荐答案
@ user249654的答案看起来很有前途。我添加了一些单元测试来验证它,确实它按预期工作。
@user249654's answer looked promising. I added some unit tests to verify it, and indeed it works as expected.
我还添加了 waitOne
代码在这里是为了防止其他人发现它有用:
The code is here in case anyone else finds it useful:
import org.junit.Assert;
import org.junit.Test;
import static java.lang.System.currentTimeMillis;
/**
* @author Drew Noakes http://drewnoakes.com
*/
public class AutoResetEventTest
{
@Test
public void synchronisesProperly() throws InterruptedException
{
final AutoResetEvent event1 = new AutoResetEvent(false);
final AutoResetEvent event2 = new AutoResetEvent(false);
final int loopCount = 10;
final int sleepMillis = 50;
Thread thread1 = new Thread(new Runnable()
{
@Override
public void run()
{
try {
for (int i = 0; i < loopCount; i++)
{
long t = currentTimeMillis();
event1.waitOne();
Assert.assertTrue("Time to wait should be within 5ms of sleep time",
Math.abs(currentTimeMillis() - t - sleepMillis) < 5);
Thread.sleep(sleepMillis);
t = currentTimeMillis();
event2.set();
Assert.assertTrue("Time to set should be within 1ms", currentTimeMillis() - t <= 1);
}
} catch (InterruptedException e) {
Assert.fail();
}
}
});
Thread thread2 = new Thread(new Runnable()
{
@Override
public void run()
{
try {
for (int i = 0; i < loopCount; i++)
{
Thread.sleep(sleepMillis);
long t = currentTimeMillis();
event1.set();
Assert.assertTrue("Time to set should be within 1ms", currentTimeMillis() - t <= 1);
t = currentTimeMillis();
event2.waitOne();
Assert.assertTrue("Time to wait should be within 5ms of sleep time",
Math.abs(currentTimeMillis() - t - sleepMillis) < 5);
}
} catch (InterruptedException e) {
Assert.fail();
}
}
});
long t = currentTimeMillis();
thread1.start();
thread2.start();
int maxTimeMillis = loopCount * sleepMillis * 2 * 2;
thread1.join(maxTimeMillis);
thread2.join(maxTimeMillis);
Assert.assertTrue("Thread should not be blocked.", currentTimeMillis() - t < maxTimeMillis);
}
@Test
public void timeout() throws InterruptedException
{
AutoResetEvent event = new AutoResetEvent(false);
int timeoutMillis = 100;
long t = currentTimeMillis();
event.waitOne(timeoutMillis);
long took = currentTimeMillis() - t;
Assert.assertTrue("Timeout should have occurred, taking within 5ms of the timeout period, but took " + took,
Math.abs(took - timeoutMillis) < 5);
}
@Test
public void noBlockIfInitiallyOpen() throws InterruptedException
{
AutoResetEvent event = new AutoResetEvent(true);
long t = currentTimeMillis();
event.waitOne(200);
Assert.assertTrue("Should not have taken very long to wait when already open",
Math.abs(currentTimeMillis() - t) < 5);
}
}
AutoResetEvent重载接受超时
AutoResetEvent with overload that accepts a timeout
public class AutoResetEvent
{
private final Object _monitor = new Object();
private volatile boolean _isOpen = false;
public AutoResetEvent(boolean open)
{
_isOpen = open;
}
public void waitOne() throws InterruptedException
{
synchronized (_monitor) {
while (!_isOpen) {
_monitor.wait();
}
_isOpen = false;
}
}
public void waitOne(long timeout) throws InterruptedException
{
synchronized (_monitor) {
long t = System.currentTimeMillis();
while (!_isOpen) {
_monitor.wait(timeout);
// Check for timeout
if (System.currentTimeMillis() - t >= timeout)
break;
}
_isOpen = false;
}
}
public void set()
{
synchronized (_monitor) {
_isOpen = true;
_monitor.notify();
}
}
public void reset()
{
_isOpen = false;
}
}
这篇关于Java相当于.Net的AutoResetEvent?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!