java 线程只执行一次_java – 如何确保方法只执行一次并且只从一个线程执行?...

@ ShayHaned的解决方案使用锁定.您可以通过AtomicBoolean使其更高效,如:

AtomicBoolean wasRun = new AtomicBoolean(false);

CountDownLatch initCompleteLatch = new CountDownLatch(1);

public void initialize() {

if (!wasRun.getAndSet(true)) {

List metadata = getMetadata(true);

List process = getProcess();

if (!metadata.isEmpty() && !process.isEmpty()) {

Manager.setAllMetadata(metadata, process);

}

startBackgroundThread();

initCompleteLatch.countDown();

} else {

log.info("Waiting to ensure initialize is done.");

initCompleteLatch.await();

log.warn("I was already run");

}

}

以上假设您不必等待startBackgroundThread中的工作完成.如果你这样做,解决方案就变成:

AtomicBoolean wasRun = new AtomicBoolean(false);

CountDownLatch initCompleteLatch = new CountDownLatch(1);

public void initialize() {

if (!wasRun.getAndSet(true)) {

List metadata = getMetadata(true);

List process = getProcess();

if (!metadata.isEmpty() && !process.isEmpty()) {

Manager.setAllMetadata(metadata, process);

}

// Pass the latch to startBackgroundThread so it can

// call countDown on it when it's done.

startBackgroundThread(initCompleteLatch);

} else {

log.info("Waiting to ensure initialize is done.");

initCompleteLatch.await();

log.warn("I was already run");

}

}

这样做的原因是AtomicBoolean.getAndSet(true)将在一个原子操作中返回先前设置的值并使新值为true.因此,获取方法的第一个线程将返回false(因为变量初始化为false),并且原子地将其设置为true.由于第一个线程返回false,它将在if语句中获取第一个分支,并且您的初始化将会发生.任何其他调用都会发现wasRun.getAndSet返回true,因为第一个线程将其设置为true,因此它们将获取第二个分支,您将获得所需的日志消息.

CountDownLatch初始化为1,因此除第一次调用之外的所有线程都在等待它.它们将阻塞,直到第一个线程调用countDown,这将把计数设置为0,释放所有等待的线程.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值