有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java以下同步块的目的是什么?

我在OpenCMS上遇到了稳定性问题。在执行线程转储时,许多线程(400个)在以下代码中等待synchronized (m_processingFiles)块:

public class CmsJspLoader ... {
...

private static Set m_processingFiles = Collections.synchronizedSet(new HashSet());

...
...
...
public String updateJsp(...) {
....

while (m_processingFiles.contains(jspVfsName)) {
    // wait a little bit until the first thread finishes
    try {
        synchronized (m_processingFiles) {
            m_processingFiles.wait(100);
        }
    } catch (InterruptedException e) {
        // ignore
    }
}
...
}
...
}

该代码是OpenCMS的一部分。 代码中没有notify()。在显示的sync块中,状态或读取共享变量没有变化。 然而,有400个线程在等待它,这意味着,只要通过这个sync最后一个线程应该等待40秒

我只是不明白它的目的。有什么我没看到的吗


共 (1) 个答案

  1. # 1 楼答案

    如果没有notify或notifyAll呼叫,这基本上就像100毫秒的睡眠。100毫秒后,线程将恢复并继续。假设同步块中只有等待,那么这只是一种奇怪的睡眠方式。触发memory barrier的同步块可能会造成其他一些影响。所以可能存在一些微妙的线程安全问题

    在这里解释线程转储时需要注意的一件事是,被阻塞的400个线程是在等待进入同步块还是在等待?当一个线程进入wait时,它实际上会从synchronized块中释放锁,以便另一个线程可以进入它。当线程从等待中醒来时,将重新获得锁

    如果线程转储表示“等待监视器输入”,那么一个线程在同步块中,而所有其他线程都试图输入。这表明您在这里有一个主要的并发问题

    但是,如果线程转储显示类似“in Object.wait()”的内容,则表示线程处于100ms等待状态,其他线程可以自由进入同步块。在本例中,这意味着循环条件仍然为false,所以请查看这一侧发生了什么,而不是等待线程发生了什么

    也就是说,无论进程的另一端是什么,如果可以执行notify/notifyAll,那么就可以减少唤醒和检查线程是否仍处于睡眠状态的延迟和成本