Java相当于.Net的AutoResetEvent吗?

如何获得与Java中的AutoResetEvent等效的语义?(有关ManualResetEvent。

回答:

@ user249654的答案看起来很有希望。我添加了一些单元测试来验证它,并且确实可以按预期工作。

我还添加了一个重载waitOne,需要超时。

如果其他人觉得它有用,则在这里提供代码:

单元测试

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接受超时

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吗? 的全部内容, 来源链接: utcz.com/qa/405838.html

回到顶部