我正在对Java中的事件回调处理框架进行压力测试,该框架在可能的情况下大量使用并发性,从而在数据竞争可能时使用同步方法和语句。在一个名为testDispatchWorstCase的恰当命名的单元测试中,任何地方都会有100到500个线程同时启动,每个线程都会调用具有同步语句的方法,这些语句利用称为MasterSemaphore的单个控制器对象的监视器。当使用100个线程进行测试时,有时一切都很完美,有时我会在一个或多个synchronized语句和/或方法中遇到一个stackoverflow异常。当使用500个线程进行测试时,我几乎总是在一个或多个同步语句和/或方法中遇到一个stackoverflow异常。Java并发性:导致StackOverflowError异常的同步语句/方法
MasterSemaphore提供了用于锁定同步语句的监视器,并提供了一些事件处理方法,这些方法被调用来协调各种线程对资源的访问。鉴于此,我认为可能使用MasterSemaphore的成员对象,因为监视器提供者可以解决问题 - 不过这只会导致死锁;数百个线程在eclipse的调试器线程视图中处于'monitor'状态,并且一直保持这种状态。 我的问题如下:
如何对象的监视器存储和跟踪对符合本显示器的锁线程参考?
为什么我会遇到使用MasterSemaphore成员对象的监视器提供程序的死锁?我是否需要在同步语句中显式调用wait ... notifyAll?
当数百个线程受到一个对象的监视器锁定时,什么可能导致同步语句中的堆栈溢出?
堆栈跟踪为:
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)
你能发布StackOverflowException的堆栈跟踪吗? – 2013-05-06 20:14:41
StackOverflow异常与同步问题不应有任何关系。听起来像完全不同的问题。同步只会导致线程阻塞,并且会以串行方式执行而不是并行执行方法。你根本不需要等待/通知。 – 2013-05-06 20:23:08
我不希望堆栈溢出来自同步相关的问题。这可能是一个不同的错误。我看到的唯一例外是你在Android上这样做。 JavaVM是否根据有多少线程来调整堆栈大小? Java通常为每个线程提供512k的堆栈(注意:严重依赖于许多因素),但是也许Android是适应性强的,并且可以为您提供细小的微小堆栈? – 2013-05-06 20:47:07