在我看来,好像Object.wait的超时版本很少可以原样使用。这是因为:
带有谓词作为参数的C++ version似乎使其正确。 Object中带有签名的相应Java方法
boolean wait(long timeOutMillis, BooleanSupplier condition)
可以方便地使用如下:
Object obj = ...;
BooleanSupplier condition = ...;
synchronized (obj) {
if (obj.wait(1000, condition)) {
// condition is fulfilled
} else {
// timeout happened
}
}
作为一种解决方法,我可以使用以下丑陋的帮助方法:
public static boolean safeWait(Object waitObject, long timeOutMillis, BooleanSupplier condition) throws InterruptedException {
if (condition.getAsBoolean()) {
return true;
}
long rest = timeOutMillis;
while (true) {
long t0 = System.currentTimeMillis();
waitObject.wait(rest);
long t1 = System.currentTimeMillis();
long waited = t1 - t0;
if (condition.getAsBoolean()) {
return true;
}
rest = rest - waited;
if (rest <= 0) {
return false;
}
}
}
我最好提出一些问题:
答案 0 :(得分:1)
答案 1 :(得分:1)
Object.wait()有一些限制,这就是Java引入Lock的原因。并且通过使用“trylock()”方法,如果其他线程已经获取了锁,则代码不会阻塞。
见下文:
Boolean workDone = false;
while (!workDone) {
Lock lock = new ReentrantLock();
Boolean lockAcquired = false;
try {
lockAcquired = lock.tryLock(5, TimeUnit.SECONDS);
} catch (InterruptedException e) { // this exception will be thrown if current thread is interrupted while acquiring the lock or has its interrupted status set on entry to "tryLock" method.
Thread.currentThread().interrupt(); // this thread's interrupt status will be set to "true" (this is needed because the current thread's interrupted status was cleared by InterruptedException)
System.out.println(Thread.currentThread().isInterrupted()); // true
}
if (Thread.currentThread().isInterrupted()) {
// close resources. finish as quick as possible
}
if (lockAcquired) {
// you have the lock. you can execute the critical section of the code (read/modify mutable shared state)
lock.unlock(); // remember to release the lock at the end of your critical section.
workDone = true;
}
}