1

我在使用 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 秒!!!

我根本不明白它的目的。有什么我没看到的吗?

4

2 回答 2

2

如果没有 notify 或 notifyAll 调用,这基本上就像 100 毫秒的睡眠。100 毫秒后,线程将重新唤醒并继续。假设在同步块中除了等待之外什么都没有,那么这只是一种奇怪的睡眠方式。同步块触发内存屏障可能会导致其他一些影响。因此,可能存在一些微妙的线程安全问题。

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

如果线程转储说“等待监视器进入”之类的内容,则一个线程位于同步块中,而所有其他线程都在尝试进入。这表明您在这里有一个主要的并发问题。

但是,如果线程转储显示类似“in Object.wait()”的内容,则表示线程处于 100 毫秒等待中,并且其他线程可以自由进入同步块。在这种情况下,这意味着循环条件仍然是错误的,所以看看那边发生了什么,而不是等待线程发生了什么。

也就是说,如果可以在进程的另一端执行 notify / notifyAll 时,它将减少唤醒和检查线程是否仍应处于睡眠状态的延迟和成本。

于 2012-09-15T07:11:38.447 回答
2

代码中必须有某个地方线程添加jspVfsNamem_processingFiles,做更多的工作,然后jspVfsNamem_processingFiles. 如果不是这种情况,那么您的其他线程将wait()永远处于该while循环中。出于某种原因,实现者不希望任何其他线程updateJsp在其他处理正在进行时执行。

我建议您检查代码以了解jspVfsName实际情况,并找到可以在代码中添加/删除它的位置m_processingFiles。或许那时你也会明白为什么作者不想updateJsp在 while jspVfsNameis in 中运行m_processingFiles

一旦你发现,你可以检查那个“其他”代码,看看是否jspVfsName可以添加到m_processingFiles并且从不删除。如果是这样,那(自然)会导致活锁,这可以解释您的稳定性问题。

或者可能updateJsp是被非常频繁地调用,并且修改的“其他”代码m_processingFiles也被非常频繁地调用,以至于它导致了主要的并发瓶颈?您的应用程序是否有问题导致updateJsp被调用的频率比应有的频率高(可能是在每个请求上,而不是每次将新的 JSP 文件放在服务器上时)?

If updateJsp is running very frequently, but it's not caused by a problem with your app, you could try simply shorten the wait() period. That shouldn't hurt anything -- it will just make the waiting threads check whether jspVfsName is still in m_processingFiles more frequently. 100ms is a long, long time in CPU terms!

于 2012-09-15T07:15:18.907 回答