gpt4 book ai didi

java - 如何确保一个方法只被多个线程调用一次?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:52:10 24 4
gpt4 key购买 nike

我有以下结构:

public void someMethod(){  
//DO SOME STUFF
try{
doSomeProcessing();
}
catch (Exception e){
loadSomeHeavyData();
doSomeProcessing();
}
}

someMethod 方法可能 被多个线程并发调用。 doSomeProcessing 可能 抛出异常(它在后端使用了一些可能过时的数据)。
如果抛出异常,则 loadSomeHeavyData(); 会执行一些耗时的任务,比如说“更新”所有当前数据,然后我可以调用 doSomeProcessing();。< br/>问题:如何确保 loadSomeHeavyData(); 只被调用一次?如果我在 loadSomeHeavyData(); 的条目中放置一些原子标志,那么我无法确定何时应该清除它。
我该如何解决这个问题?请注意:我无法修改 doSomeProcessing();,因为它是一个外部 API,我正在使用装饰器模式来使用它。

最佳答案

您的 loadSomeHeavyData 方法可以使用阻塞机制让所有线程等待直到完成更新,但只让其中一个线程实际执行更新:

private final AtomicBoolean updateStarted = new AtomicBoolean();
private final CountDownLatch updateFinished = new CountDownLatch(1);

public void loadSomeHeavyData() {
if (updateStarted.compareAndSet(false, true)) {
//do the loading
updateFinished.countDown();
} else {
//update already running, wait
updateFinished.await();
}
}

注意我的假设:

  • 您希望所有线程等待加载完成,以便它们可以使用更新后的数据第二次调用 doSomeProcessing
  • 您只能调用一次 loadSomeHeavyData,否则您将需要重置标志和 CountdownLatch(这可能不是最合适的机制)。

编辑

您最近的评论表明您实际上想多次调用 loadSomeHeavyData,只是一次不超过一次。

private final Semaphore updatePermit = new Semaphore(1);

public void loadSomeHeavyData() {
if (updatePermit.tryAcquire()) {
//do the loading and release updatePermit when done
updatePermit.release();
} else {
//update already running, wait
updatePermit.acquire();
//release the permit immediately
updatePermit.release();
}
}

关于java - 如何确保一个方法只被多个线程调用一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13356702/

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