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

多线程场景下仅访问同一同步方法时锁定线程的实现方案咨询

这个问题的核心在于你对静态synchronized方法的锁机制理解有点偏差——静态同步方法锁的是类的Class对象(比如你的类是ErrorLogger的话,锁就是ErrorLogger.class),所有静态同步方法共享这同一把锁。所以不管线程调用的是哪个静态同步方法,只要有一个线程占着锁,其他线程就得等,这就是你遇到的问题。

针对你的writeError方法,我给你两个最直接的可行方案:


方案1:使用专属的静态锁对象替换方法级synchronized

给writeError方法单独分配一个私有静态锁对象,这样只有调用这个方法的线程才会竞争这把锁,其他静态同步方法(如果有的话)可以用各自的锁,互相不干扰。代码示例:

// 定义专属的静态锁对象,private保证外部无法访问
private static final Object WRITE_ERROR_LOCK = new Object();

public static void writeError(Exception err) {
    // 仅在这个代码块内锁定专属锁
    synchronized (WRITE_ERROR_LOCK) {
        String time = longDate();
        try {
            FileWriter path = new FileWriter("ERROR - " + time + ".txt", true);
            err.printStackTrace(new PrintWriter(path));
            path.flush();
        } catch (IOException e) {
            // 建议不要空catch,至少打印日志方便排查问题
            e.printStackTrace();
        }
    }
}

原理很简单:每个需要独立锁定的方法用自己的锁对象,不同方法的锁之间完全隔离,只有同一方法的并发调用才会触发等待。


方案2:使用ReentrantLock实现更灵活的锁定

如果你需要更灵活的锁控制(比如公平锁、可中断锁等),可以用java.util.concurrent.locks.ReentrantLock替代synchronized。代码示例:

import java.util.concurrent.locks.ReentrantLock;

// 定义专属的ReentrantLock
private static final ReentrantLock WRITE_ERROR_LOCK = new ReentrantLock();

public static void writeError(Exception err) {
    WRITE_ERROR_LOCK.lock(); // 获取锁
    try {
        String time = longDate();
        try {
            FileWriter path = new FileWriter("ERROR - " + time + ".txt", true);
            err.printStackTrace(new PrintWriter(path));
            path.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } finally {
        WRITE_ERROR_LOCK.unlock(); // 必须在finally里释放锁,防止异常导致锁泄漏
    }
}

这个方案的优势是锁的操作更可控,比如你可以用tryLock()尝试获取锁而不是一直等待,不过对于你的需求来说,两种方案都能完美解决问题。


最后提个小提醒:你的longDate()方法虽然不是同步的,但要确保它本身是线程安全的——如果它内部有共享变量或者非线程安全的操作,可能会导致时间字符串出现异常,这一点也要注意哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:42:28