Lock sharedLock = new ReentrantLock();
Condition condition = lock.newCondition();主螺纹:
sharedLock.lock();
childThread.start();
condition.await(5, TimeUnit.SECONDS);
sharedLock.unlock();子线程:
sharedLock.lock();
//do something, may take a long time
Thread.sleep(10);// sleep to simulate a long execution
condition.signal();
sharedLock.unlock();假设子线程发送网络请求并等待响应,我希望主线程等待最多5秒,如果超时,请重试请求。但是当await()超时时,它无法获得锁,因为子线程仍然持有锁,所以它仍然等待锁,直到子线程释放它,这需要10秒。
如何实现我的要求:主线程等待子线程的信号,但有一个有限度的超时?
发布于 2016-06-11 15:31:22
这不是你应该怎么做的,你应该:
ExecutorService (线程池),您应该检查类Executors的方法,以便在您的情况下选择最好的方法,但是Executors.newFixedThreadPool是一个很好的开始。FutureTask提交到线程池getTimeoutException以下是如何做到这一点:
// Total tries
int tries = 3;
// Current total of tries
int tryCount = 1;
do {
// My fake task to execute asynchronously
FutureTask<Void> task = new FutureTask<>(
() -> {
Thread.sleep(2000);
return null;
}
);
// Submit the task to the thread pool
executor.submit(task);
try {
// Wait for a result during at most 1 second
task.get(1, TimeUnit.SECONDS);
// I could get the result so I break the loop
break;
} catch (TimeoutException e) {
// The timeout has been reached
if (tryCount++ == tries) {
// Already tried the max allowed so we throw an exception
throw new RuntimeException(
String.format("Could execute the task after %d tries", tries),
e
);
}
}
} while (true);如何实现我的要求:主线程等待子线程的信号,但有一个有限度的超时?
以下是如何实现您的需求:
主螺纹:
lock.lock();
try {
childThread.start();
condition.await(5, TimeUnit.SECONDS);
} finally {
sharedLock.lock();
}子线程:
try {
//do something, may take a long time
Thread.sleep(10);// sleep to simulate a long execution
} finally {
// Here we notify the main thread that the task is complete whatever
// the task failed or not
lock.lock();
try {
condition.signal();
} finally {
lock.unlock();
}
}正如您所看到的那样,任务不能在关键部分内执行,我们只获取锁来通知主线程仅此而已。否则,如果在超时后在关键部分执行任务,则主线程仍然需要再次获取锁,而且由于锁实际上是子线程所拥有的,因此它需要等待任务的结束,这使得超时完全无用。
NB: I将sharedLock重命名为ReentrantLock是一种独占锁,而不是共享锁,如果需要共享锁,请检查类Semaphore以定义许可总量。
发布于 2018-05-23 19:06:49
问题中的有效混淆是因为"Thread.sleep(10)“是在锁块内完成的。当等待(长时间,TimeUnit单元)由于超时而返回时,它仍然需要锁。因此,正如在另一个答案中所建议的,长时间运行的任务不应该在锁中才能正常工作。但最好有适当的文件来强调这一事实。例如,如果我们等待(5,TimeUnit.SECONDS),即等待5秒,并且在调用后10秒锁可用,那么即使锁在返回的时刻可用,它仍然会返回false。
https://stackoverflow.com/questions/37764805
复制相似问题