java - swingWorker调用的synchronized方法被中断?

标签 java multithreading logging log4j synchronized

我有一个同步函数,它是从另一个函数的循环中在新线程中启动的,并且有很多调用它。所以我有:

foo(){
new SwingWorker() {
                @Override
                public void doInBackground() {
                    sync_foo();
                }
            }.execute();
} catch (IOException e) {
            log.error("", e);
        }
}

sync_foo 定义为:

private synchronized void sync_foo() {
}

我在 sync_foo 中放置了一些调试行,以检查它是否按我的预期工作。所以我有:

private synchronized void sync_foo() {
    final Logger log = Logger.getLogger(getClass());
    log.info("start");
    ...
    log.info("finish");
}

这里的记录器是 Log4J,据我所知,它确实是线程安全的。我注意到在日志文件中有时有两个后续的“开始”。因此,我在末尾附近添加了另一行 log.info("stillalicious") 并不断将其越来越靠近 log.info("start"); 到看看我是否曾经停止获得双 starts 并且总是在两者之间获得 stilllive ,但我仍然得到它,最后我把它放在下一行 log.info("开始");:

private synchronized void sync_foo() {
    final Logger log = Logger.getLogger(getClass());
    log.info("start");
    log.info("still alive");
    ...
    log.info("finish");
}

但时不时地,我仍然得到:

start
start

我觉得这很令人费解。看来该方法以某种方式被中断,但我不明白如何中断。我应该补充一点,sync_foo() 仅从 foo() 调用,并且我没有收到任何类型的异常或错误。

所以问题是:

  • 一般来说,方法被自身中断的可能原因有哪些?

  • 我知道 Swing Worker 可能有自己的处理线程执行的方法。我上面使用的 SwingWorker 实际上已被重写,其定义如 here 中所示。 。此扩展中是否有任何内容可能导致错过相关异常?

最佳答案

同步取决于共享锁,因此如果您看到多个线程同时调用同步的内容的行为,则意味着它们没有使用相同的锁。听起来好像在不同的对象上调用了sync_foo。在方法上使用同步意味着对象实例上的监视器由想要进入该方法的线程获取,因此如果在不同对象上调用该方法,则不会有共享锁,也不会阻止线程当另一个线程正在另一个对象上执行该方法时,进入一个对象上的方法。

你可以像这样创建一个类级锁:

public static final Object LOCK = new Object();

并将方法更改为

private void sync_foo() {
    synchronized(LOCK) {
        final Logger log = Logger.getLogger(getClass());
        log.info("start");
        log.info("still alive");
        ...
        log.info("finish");
    }
}

因此,无论调用的是哪个实例,调用sync_foo的所有对象都将使用相同的锁。

关于java - swingWorker调用的synchronized方法被中断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31480100/

相关文章:

Tomcat 服务器日志的文件名中有日期 - rotatable=false 不起作用

logging - 如何从我的 map/reduce 应用程序登录?

java - JSP 中的枚举

java - fragment 中的 Mapbox onStop

c# - 后台 worker 调用之间是否保留了线程本地存储?

java - 不同任务的ThreadPoolExecutor

ruby-on-rails - 如何测试 ActiveSupport::TaggedLogging

java - 使用 Perlin 噪声生成平铺地形 - Java

java - 套接字流写入

java - 字节数组多线程读写