You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确实现:其他线程访问同步块时抛出MyException?

解决方案

核心问题分析

现有实现的关键缺陷是锁状态检查与锁获取不是原子操作,两个线程可能同时检测到锁未被占用,进而先后进入同步块,导致并行执行的风险。

正确实现方案

结合你的两个需求(禁止并行执行、1分钟内重复调用抛出异常),可以通过ReentrantLock的tryLock()原子操作+原子时间记录来实现:

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
import static java.util.Objects.requireNonNull;

public class YourClass {
    private final ReentrantLock lock = new ReentrantLock();
    private final AtomicLong lastExecutionEndTime = new AtomicLong(0);
    // 定义1分钟的时间间隔(毫秒)
    private static final long MIN_EXECUTION_INTERVAL = TimeUnit.MINUTES.toMillis(1);

    void verySlowMethod(String thisOperationId) {
        requireNonNull(thisOperationId);

        long currentTime = System.currentTimeMillis();
        // 检查距离上次执行结束是否不足1分钟
        if (currentTime - lastExecutionEndTime.get() < MIN_EXECUTION_INTERVAL) {
            throw new MyException();
        }

        // 原子性尝试获取锁,立即返回结果,不阻塞
        if (!lock.tryLock()) {
            throw new MyException();
        }

        try {
            // 执行你的业务操作代码
            // ...
        } finally {
            // 无论业务是否异常,都要释放锁并更新执行结束时间
            lastExecutionEndTime.set(System.currentTimeMillis());
            lock.unlock();
        }
    }
}

方案说明

  1. 原子锁获取:tryLock()方法会原子性地尝试获取锁,成功则返回true,失败直接返回false,彻底避免了"检查-加锁"的竞态条件。
  2. 时间间隔控制:使用AtomicLong记录上次执行结束时间,保证多线程环境下时间读取与更新的原子性,防止时间判断出现竞态。
  3. 锁安全释放:将锁的释放和时间更新放在finally块中,确保无论业务代码是否抛出异常,锁都能被正确释放,避免死锁风险。

简化版(仅处理并行执行)

如果不需要1分钟间隔的限制,仅保留并行控制逻辑即可:

private final ReentrantLock lock = new ReentrantLock();

void verySlowMethod(String thisOperationId) {
    requireNonNull(thisOperationId);

    if (!lock.tryLock()) {
        throw new MyException();
    }

    try {
        // 业务操作代码
        // ...
    } finally {
        lock.unlock();
    }
}

内容的提问来源于stack exchange,提问作者Krzysztof

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 13:07:40