gpt4 book ai didi

Java 并发数 : synchronized statements/methods causing StackOverflowError exception

转载 作者:行者123 更新时间:2023-11-30 03:37:31 25 4
gpt4 key购买 nike

我正在对 Java 中的事件回调处理框架进行压力测试,该框架在可能的情况下大量使用并发性,因此在可能发生数据争用时使用同步方法和语句。在名为 testDispatchWorstCase 的单元测试中,将同时启动 100 到 500 个线程,每个线程都调用带有同步语句的方法,这些语句利用名为 MasterSemaphore 的单个 Controller 对象的监视器。使用 100 个线程进行测试时,有时一切正常,有时我会在一个或多个同步语句和/或方法中遇到 stackoverflow 异常。在使用 500 个线程进行测试时,我几乎总是会在一个或多个同步语句和/或方法中遇到 stackoverflow 异常。

MasterSemaphore提供了用于锁住synchronized语句的监视器,也提供了一些事件处理方法,调用这些方法来协调各个线程对资源的访问。鉴于此,我想也许可以使用 MasterSemaphore 的一个成员对象,它没有其他职责,作为监视器提供者可以解决问题——不幸的是,这只会导致死锁;在 Eclipse 调试器的线程 View 中,数百个线程卡在“监控”状态,并永远保持这种状态。我的问题如下:

  1. 对象的监视器如何存储和跟踪对受此监视器锁定的线程的引用?

  2. 为什么我在使用监视器提供程序的 MasterSemaphore 成员对象时遇到了死锁?我是否需要在同步语句中显式调用 wait...notifyAll?

  3. 当数百个线程受制于一个对象的监视器锁时,什么可能导致同步语句中的堆栈溢出?

堆栈跟踪是:

01-02 07:47:44.910 27698 27842 E AndroidRuntime: FATAL EXCEPTION: HPCHead Spawned 
Thread #24

01-02 07:47:44.910 27698 27842 E AndroidRuntime: java.lang.StackOverflowError

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:147)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
java.lang.IntegralToString.convertInt(IntegralToString.java:209)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
java.lang.IntegralToString.appendInt(IntegralToString.java:173)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
java.lang.StringBuilder.append(StringBuilder.java:139)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
java.lang.Thread.toString(Thread.java:1098)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
addRegistrantForCallback_PrefabEventHandling(MasterSemaphore.java:2524)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterEventHandler$EventIDFreedHandler.
onUpdateNeeded(MasterEventHandler.java:221)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.CallbackDataRecord.
postToQueueHead(CallbackDataRecord.java:107)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
onFinishedEventProcessing(MasterSemaphore.java:1219)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
addRegistrantForCallback_PrefabEventHandling(MasterSemaphore.java:2597)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterEventHandler$EventIDFreedHandler.
onUpdateNeeded(MasterEventHandler.java:221)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.CallbackDataRecord.
postToQueueHead(CallbackDataRecord.java:107)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
onFinishedEventProcessing(MasterSemaphore.java:1219)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
addRegistrantForCallback_PrefabEventHandling(MasterSemaphore.java:2597)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterEventHandler$EventIDFreedHandler
.onUpdateNeeded(MasterEventHandler.java:221)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.CallbackDataRecord.
postToQueueHead(CallbackDataRecord.java:107)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
onFinishedEventProcessing(MasterSemaphore.java:1219)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
addRegistrantForCallback_PrefabEventHandling(MasterSemaphore.java:2597)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterEventHandler$EventIDFreedHandler.
onUpdateNeeded(MasterEventHandler.java:221)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.CallbackDataRecord.
postToQueueHead(CallbackDataRecord.java:107)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
onFinishedEventProcessing(MasterSemaphore.java:1219)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
addRegistrantForCallback_PrefabEventHandling(MasterSemaphore.java:2597)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterEventHandler$EventIDFreedHandler.
onUpdateNeeded(MasterEventHandler.java:221)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.CallbackDataRecord.
postToQueueHead(CallbackDataRecord.java:107)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
onFinishedEventProcessing(MasterSemaphore.java:1219)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
addRegistrantForCallback_PrefabEventHandling(MasterSemaphore.java:2597)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterEventHandler$EventIDFreedHandler.
onUpdateNeeded(MasterEventHandler.java:221)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.CallbackDataRecord.
postToQueueHead(CallbackDataRecord.java:107)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
onFinishedEventProcessing(MasterSemaphore.java:1219)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
addRegistrantForCallback_PrefabEventHandling(MasterSemaphore.java:2597)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterEventHandler$EventIDFreedHandler.
onUpdateNeeded(MasterEventHandler.java:221)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.CallbackDataRecord.
postToQueueHead(CallbackDataRecord.java:107)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
onFinishedEventProcessing(MasterSemaphore.java:1219)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
addRegistrantForCallback_PrefabEventHandling(MasterSemaphore.java:2597)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterEventHandler$EventIDFreedHandler.
onUpdateNeeded(MasterEventHandler.java:221)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.CallbackDataRecord.
postToQueueHead(CallbackDataRecord.java:107)

01-02 07:47:44.910 27698 27842 E AndroidRuntime: at
com.hdradio.hdradiomanagerjc.hpc.MasterSemaphore.
onFinishedEventProcessing(MasterSemaphore.java:1219)

最佳答案

问题的答案:

  1. 这是一个 article that describes how synchronization using object monitors works

  2. 我不确定您为什么会陷入僵局。我需要查看更多代码才能提供帮助。不过,正如我在之前的评论中所说,在使用 synchronized 时,您不需要使用 wait'/notifyAll。 JVM 会自动为您处理所有锁定和等待。当然,这并不意味着您不能将自己编程到死锁情况中(这实际上很容易做到)。不过,添加 notify()` 调用不会解除死锁。

  3. 所以堆栈溢出问题来自递归调用堆栈,如下所示:

    ...

    MasterSemaphore.onFinishedEventProcessing(MasterSemaphore.java:1219)
    MasterSemaphore.addRegistrantForCallback_PrefabEventHandling(MasterSemaphore.java:2597)
    MasterEventHandler$EventIDFreedHandler.onUpdateNeeded(MasterEventHandler.java:221)
    CallbackDataRecord.postToQueueHead(CallbackDataRecord.java:107)
    MasterSemaphore.onFinishedEventProcessing(MasterSemaphore.java:1219)

所以 onFinishedEventProcessing() 被递归调用,这导致堆栈溢出。您应该看看为什么会这样(如果需要,添加一些日志记录)。

关于Java 并发数 : synchronized statements/methods causing StackOverflowError exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16406420/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com