我正在对Java中的事件回调处理框架进行压力测试,该框架在可能的情况下大量使用并发性,因此在可能发生数据争用时使用同步的方法和语句。在名为testDispatchWorstCase的适当名称的单元测试中,将同时启动100到500个线程中的任何一个,每个线程的调用方法都带有同步语句,这些语句利用称为MasterSemaphore的单个控制器对象的监视器。当使用100个线程进行测试时,有时一切运行良好,有时我在一个或多个同步语句和/或方法中遇到了stackoverflow异常。使用500个线程进行测试时,我几乎总是在一个或多个同步语句和/或方法中遇到stackoverflow异常。
MasterSemaphore提供了用于锁定同步语句的监视器,还提供了一些事件处理方法,这些方法被称为协调各种线程对资源的访问。鉴于此,我想也许是使用MasterSemaphore的成员Object,该成员没有其他职责,因为监视器提供程序将解决此问题-不幸的是,这只会导致死锁;数百个线程在eclipse调试器的线程视图中停留在“监视”状态,并一直保持这种状态。
我的问题如下:
对象的监视器如何存储和跟踪对受此监视器锁定的线程的引用?
为什么我为监视器提供程序使用MasterSemaphore的成员对象陷入僵局?我是否需要在syncsizes语句中显式调用wait ... notifyAll?
当数百个线程受到一个对象的监视器锁定时,可能导致同步语句中的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)
最佳答案
您的问题的答案:
这是一个article that describes how synchronization using object monitors works
我不确定您为什么会陷入僵局。我需要查看更多代码来帮助实现这一点。但是,正如我在较早的评论中所说的那样,您不必使用wait'/
notifyAll when using
synchronized . 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()`调用并不会消除死锁。
因此,堆栈溢出问题来自如下所示的递归调用堆栈:
...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()
被递归调用,这导致堆栈溢出。您应该查看一下为什么会发生这种情况(如果需要,请添加一些日志记录)。