autoresetevent java,Java相当于.Net的AutoResetEvent?

What should I use to get semantics equivalent to AutoResetEvent in Java?

(See this question for ManualResetEvent).

解决方案

@user249654's answer looked promising. I added some unit tests to verify it, and indeed it works as expected.

I also added an overload of waitOne that takes a timeout.

The code is here in case anyone else finds it useful:

Unit Test

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 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;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值