繁体   English   中英

Java并发性:导致StackOverflowError异常的同步语句/方法

[英]Java concurrency: synchronized statements/methods causing StackOverflowError exception

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

MasterSemaphore提供了用于锁定同步语句的监视器,还提供了一些事件处理方法,这些方法被称为协调各种线程对资源的访问。 鉴于此,我认为也许可以使用MasterSemaphore的成员Object,而该成员没有其他职责,因为监视器提供程序可以解决此问题–不幸的是,这只会导致死锁。 数百个线程在eclipse调试器的线程视图中停留在“监视”状态,并一直保持这种状态。 我的问题如下:

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

  2. 为什么我为监视器提供程序使用MasterSemaphore的成员对象陷入僵局? 我是否需要在syncsizes语句中显式调用wait ... notifyAll?

  3. 当数百个线程受到一个对象的监视器锁定时,可能导致同步语句中的stackoverflow?

堆栈跟踪为:

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. 这是一篇描述使用对象监视器进行同步的工作方式的文章

  2. 我不确定您为什么会陷入僵局。 我需要查看更多代码来帮助实现这一点。 但是,正如我在较早的评论中所说的那样, when using sync when using ,您不需要使用wait'/ notifyAll . The JVM handles all the locking and waiting automatically for you. Of course, this doesn't mean that you can't program yourself into a deadlock situation (that's actually pretty easy to do). Adding . The JVM handles all the locking and waiting automatically for you. Of course, this doesn't mean that you can't program yourself into a deadlock situation (that's actually pretty easy to do). Adding . The JVM handles all the locking and waiting automatically for you. Of course, this doesn't mean that you can't program yourself into a deadlock situation (that's actually pretty easy to do). Adding 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()被递归调用,这导致堆栈溢出。 您应该查看一下为什么会发生这种情况(如果需要,请添加一些日志记录)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM