【转】[Java] 防止并发的多种写法

来自:阿里的 通义灵码

要确保在Java中同一方法被多个线程同时调用时,只有其中一个成功执行,可以采用几种并发控制策略。以下是几种实现方式:

1. 使用ReentrantLock的tryLock()

import java.util.concurrent.locks.ReentrantLock;

public class SingletonExecution {
    private static final ReentrantLock lock = new ReentrantLock();

    public boolean executeOnce() {
        // 尝试获取锁,如果已经锁住则立即返回false,否则获取锁并执行
        if (lock.tryLock()) {
            try {
                // 执行业务逻辑
                performAction();
                return true; // 成功执行
            } finally {
                lock.unlock(); // 确保锁被释放
            }
        } else {
            // 锁已被其他线程持有,表示已有其他调用者成功
            return false;
        }
    }

    private void performAction() {
        // 实际执行的业务逻辑
    }
}

2. 使用synchronized和标志位

public class SingletonExecution {
    private static boolean executed = false;

    public synchronized boolean executeOnce() {
        if (!executed) {
            // 执行业务逻辑
            performAction();
            executed = true;
            return true;
        }
        return false; // 已经有其他线程执行过了
    }

    private void performAction() {
        // 实际执行的业务逻辑
    }
}

3. 使用AtomicBoolean和CAS操作

import java.util.concurrent.atomic.AtomicBoolean;

public class SingletonExecution {
    private static final AtomicBoolean executed = new AtomicBoolean(false);

    public boolean executeOnce() {
        // 使用CAS操作,如果executed为false则设置为true并返回true,否则返回false
        return executed.compareAndSet(false, true);
    }

    // 这里可以添加执行的业务逻辑方法
}

每种方法都有其适用场景。使用tryLock()提供了非阻塞的尝试获取锁的方式,适合于那些不希望线程等待的情况。

synchronizedAtomicBoolean则分别利用内置锁和原子操作保证操作的原子性和可见性,适用于简单场景。

选择时应考虑具体需求,如是否需要阻塞、性能要求等因素。

posted on 2024-04-29 15:59  z5337  阅读(284)  评论(0)    收藏  举报