java 等待提示 事件,在Java中等待一个事件 - 它有多难?

I have a thread that updates it's state from time to time and I want a second thread to be able to wait for the first thread to be done. Something like this:

Thread 1:

while(true) {

...do something...

foo.notifyAll()

...wait for some condition that might never happen...

...

}

Thread 2:

...

foo.wait();

...

Now this looks nice and all unless Thread 1's notifyAll() runs before Thread 2's wait(), in which case Thread 2 waits until Thread 1 notifies again (which might never happen).

My possible solutions:

a) I could use a CountDownLatch or a Future, but both have the problem that they inherently only run once. That is, in Thread 1's while loop, I would need to create a new foo to wait for each time and Thread 2 would need to ask which foo to wait for. I have a bad feeling about simply writing

while(true) {

foo = new FutureTask();

...

foo.set(...);

...wait for a condition that might never be set...

...

}

as I fear that at foo = new FutureTask(), what happens when someone waited for the old foo (for "some reason", set was not called, e.g. a bug in the exception handling)?

b) Or I could use a semaphore:

class Event {

Semaphore sem;

Event() { sem = new Semaphore(1); sem . }

void signal() { sem.release(); }

void reset() { sem.acquire(1); }

void wait() { if (sem.tryAcquire(1)) { sem.release(); } }

}

But I fear that there is some race condition, if multiple threads are wait()ing for it while another one signal()s and reset()s.

Question:

Is there nothing in the Java API that resembles the Windows Event behaviour? Or, if you despise Windows, something like golang's WaitGroup (i.e. a CountDownLatch that allows countUp())? Anything?

How to do it manually:

Thread 2 cannot simply wait because of spurious wakeup and in Java there is no way to know why Object.wait() returned. So I need a condition variable that stores whether the event is signalled or not. Thread 2:

synchronized(foo) {

while(!condition) {

foo.wait();

}

}

And Thread 1 of course sets condition to true in a synchronized block. Thanks to weekens for the hint!

Is there an existing class that wraps that behaviour?

Or do I need to copy and paste the code all over?

解决方案

It is standard practice to change some state when performing notifyAll and to check some state when performing wait().

e.g.

boolean ready = false;

// thread 1

synchronized(lock) {

ready = true;

lock.notifyAll();

}

// thread 2

synchronized(lock) {

while(!ready)

lock.wait();

}

With this approach, it doesn't matter if thread 1 or thread 2 acquires the lock first.

Some coding analysis tools will give you a warning if you use notify or wait without setting a value or checking a value.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值