gpt4 book ai didi

java - 多线程 : java condition await timeout but can't return

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:14:45 25 4
gpt4 key购买 nike

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 秒。

如何实现主线程等待子线程信号但有一个有限超时的要求?

最佳答案

这不是你应该做的,你应该:

  1. 为此创建一个 ExecutorService(线程池),您应该检查 Executors 类的方法,以根据您的情况选择最佳方法,但 Executors.newFixedThreadPool 是一个好的开始
  2. 将您的任务作为 FutureTask 提交到线程池
  3. 然后超时调用get
  4. 妥善管理TimeoutException

具体做法如下:

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

How can I achieve my requirement that main thread wait child thread's signal, but have a bounded timeout?

以下是您可以如何实现您的要求:

主线程:

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();
}
}

正如你所看到的工作,任务一定不能在临界区内执行,我们只是获取锁通知主线程而已。否则,如果超时后在临界区内执行任务,主线程仍将需要再次获取锁,并且由于锁实际上由子线程拥有,因此无论如何它都需要等待直到任务结束使超时完全无用。

注意: 我将 sharedLock 重命名为 lock 因为 ReentrantLock 是独占锁而不是共享锁,如果您需要共享锁,请检查类 Semaphore 以定义许可的总量。

关于java - 多线程 : java condition await timeout but can't return,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37764805/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com