Java 解释jstack跟踪以跟踪暂停的锁

Java 解释jstack跟踪以跟踪暂停的锁,java,multithreading,concurrency,locking,jstack,Java,Multithreading,Concurrency,Locking,Jstack,我用过Samurai,我可以看到没有死锁,有几个线程正在等待,但我似乎无法准确地找出哪个锁正在暂停进程。有人能帮我吗 我不是在寻找人们猜测我的问题是什么,而是更多关于如何修改代码以更容易跟踪问题的建议。我完成了第一次发送和接收,然后程序在应该发送第二条消息时暂停。我是多线程新手,这是我第一次使用jstack 2013-04-02 23:43:12 Full thread dump OpenJDK Zero VM (22.0-b10 mixed mode): "Attach Listener"

我用过Samurai,我可以看到没有死锁,有几个线程正在等待,但我似乎无法准确地找出哪个锁正在暂停进程。有人能帮我吗

我不是在寻找人们猜测我的问题是什么,而是更多关于如何修改代码以更容易跟踪问题的建议。我完成了第一次发送和接收,然后程序在应该发送第二条消息时暂停。我是多线程新手,这是我第一次使用jstack

2013-04-02 23:43:12
Full thread dump OpenJDK Zero VM (22.0-b10 mixed mode):

"Attach Listener" daemon prio=10 tid=0x0037c880 nid=0x105b waiting on condition     [0x00000000]
java.lang.Thread.State: RUNNABLE

"Thread-3" prio=10 tid=0x0037c488 nid=0x1041 waiting on condition [0xa7ddd000]
java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0xab770958> (a     java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
    at org.dnsdojo.ryanhost.GA.MuPlusOne.RobotInterface.evaluate(RobotInterface.java:38)
    at org.dnsdojo.ryanhost.GA.MuPlusOne.RobotInterface.run(RobotInterface.java:69)
    at java.lang.Thread.run(Thread.java:722)

"Thread-1" prio=10 tid=0x0036ff10 nid=0x1036 waiting on condition [0xa7f5d000]
java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0xab770940> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at   java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
    at org.dnsdojo.ryanhost.GA.MuPlusOne.TwoWaySerialCommTest$SerialWriter.run(TwoWaySerialCommTest.java:229)
    at java.lang.Thread.run(Thread.java:722)

"Thread-0" daemon prio=10 tid=0x0036a1e8 nid=0x1035 runnable [0xa80dd000]
java.lang.Thread.State: RUNNABLE
    at gnu.io.RXTXPort.eventLoop(Native Method)
    at gnu.io.RXTXPort$MonitorThread.run(RXTXPort.java:1644)

"Service Thread" daemon prio=10 tid=0x00253440 nid=0x102b runnable [0x00000000]
java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x00251988 nid=0x102a runnable [0x00000000]
java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=10 tid=0x0020c880 nid=0x1029 in Object.wait() [0xa8ac1000]
java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xab718a88> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
    - locked <0xab718a88> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)

"Reference Handler" daemon prio=10 tid=0x00209f18 nid=0x1028 in Object.wait() [0xa8c41000]
java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xab718b10> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:503)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
    - locked <0xab718b10> (a java.lang.ref.Reference$Lock)

"main" prio=10 tid=0x00180fa8 nid=0x1022 in Object.wait() [0xb6848000]
java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xa90716a8> (a org.dnsdojo.ryanhost.GA.MuPlusOne.CandidateTest)
    at java.lang.Object.wait(Object.java:503)
    at org.dnsdojo.ryanhost.GA.MuPlusOne.MuPlusOneAlgorithm.runOnBot(MuPlusOneAlgorithm.java:120)
    - locked <0xa90716a8> (a org.dnsdojo.ryanhost.GA.MuPlusOne.CandidateTest)
    at org.dnsdojo.ryanhost.GA.MuPlusOne.MuPlusOneAlgorithm.initialFitness(MuPlusOneAlgorithm.java:72)
    - locked <0xab718bd0> (a org.dnsdojo.ryanhost.GA.MuPlusOne.MuPlusOneAlgorithm)
    at org.dnsdojo.ryanhost.GA.MuPlusOne.MuPlusOneAlgorithm.main(MuPlusOneAlgorithm.java:138)

"VM Thread" prio=10 tid=0x00204910 nid=0x1027 runnable

"VM Periodic Task Thread" prio=10 tid=0x00255130 nid=0x102c waiting on condition

JNI global references: 36
为了总结执行过程,我有一个for循环,它创建RobotInterface线程,每个线程对应一个包含位字符串的基因组。这个基因组引用保存在candidateTest中,它只是RobotInterface和调用线程在完成时发出信号的共享类

位字符串通过RobotInterface使用TwoWaySerialCommTest发送给机器人。机器人对其进行评估并返回一个适应度函数,该函数由SerialReader解析为浮点。然后将下一个字符串发送给机器人

锁定发生在第一个字符串返回机器人并发送第二个字符串之后。我可以看到第一根绳子到了机器人那里,但是第二根绳子没有。结果如下-

initialFitness method
1101010101111111001100000101011100110000100001111111001000001001101101000011100101011000000100000000110110001110
5436 [main] DEBUG org.dnsdojo.ryanhost.GA.MuPlusOne.GeneticAlgorithm  - Testing candidate
1101010101111111001100000101011100110000100001111111001000001001101101000011100101011000000100000000110110001110
1101010101111111001100000101011100110000100001111111001000001001101101000011100101011000000100000000110110001110
5853 [Thread-2] DEBUG Threadmain  - entering run of Robot Interface
5869 [Thread-2] DEBUG Threadmain  - Send Genome via serial and wait for a response
5881 [Thread-2] DEBUG Threadmain  - fitness is 0.0
1101010101111111001100000101011100110000100001111111001000001001101101000011100101011000000100000000110110001110
1101010101111111001100000101011100110000100001111111001000001001101101000011100101011000000100000000110110001110
10
Output buffer after put
1101010101111111001100000101011100110000100001111111001000001001101101000011100101011000000100000000110110001110

Buffer isn't empty

initialFitness method
1110110101110000001100101100110001001010010101011110001101010010100100111011111000011101110000001110100111001111
16593 [main] DEBUG org.dnsdojo.ryanhost.GA.MuPlusOne.GeneticAlgorithm  - Testing candidate
1110110101110000001100101100110001001010010101011110001101010010100100111011111000011101110000001110100111001111
1110110101110000001100101100110001001010010101011110001101010010100100111011111000011101110000001110100111001111
16944 [Thread-3] DEBUG Threadmain  - entering run of Robot Interface
16953 [Thread-3] DEBUG Threadmain  - Send Genome via serial and wait for a response
16964 [Thread-3] DEBUG Threadmain  - fitness is 0.0
1110110101110000001100101100110001001010010101011110001101010010100100111011111000011101110000001110100111001111
1110110101110000001100101100110001001010010101011110001101010010100100111011111000011101110000001110100111001111
10
Output buffer after put
1110110101110000001100101100110001001010010101011110001101010010100100111011111000011101110000001110100111001111

Buffer isn't empty

我的方法是消除明显不相关的线程。对你来说,很可能是这样

  • 附加侦听器
  • 服务线程
  • 信号调度器
  • Finalizer
  • 引用处理程序
  • VM线程
  • VM定期任务线程
这些是VM管理的线程,也就是说,您没有显式或隐式地创建它们

剩下
Thread-x
Main
线程

查看堆栈跟踪,可以根据您对代码的了解推断出事情等待的原因。例如,队列似乎在等待满足
条件

parking to wait for <0xab770958> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
等待停车(java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
条件
信号
唤醒,因此您可能会想一想为什么没有发送
信号
消息。由于此条件包含在队列实现中,因此问题不太可能不是您忘记调用
信号。然而,您可能忘记了调用某个反过来又会调用它的对象?或者无意中设置了一个从未满足条件的情况

因此,我将着眼于事件流,以确保锁定的任何东西都被解锁,或者任何可能导致活锁的条件(请记住,JVM/samauri可以检测死锁,但不能检测活锁)

这是我对如何解决这个问题的总体想法。如果您想将代码发布到某个地方,那么它将有助于实际调试它/提供更多关于人们如何解决它的见解


祝你好运

谢谢,我已经在问题中添加了代码,正如您所看到的,这是一个非常复杂的问题:(根据你的一般回答,我目前正在研究这个问题,这个答案很有帮助。我想我的问题是在读序列时遇到的RobotInterface类的问题,可能是在dual try/catch中锁没有被正确释放?因此,在我把头撞掉一段时间后,我发现这个问题和串行连接没有确认和响应某些字符串有关,不过您的建议确实帮助我排除了线程问题,所以非常感谢
initialFitness method
1101010101111111001100000101011100110000100001111111001000001001101101000011100101011000000100000000110110001110
5436 [main] DEBUG org.dnsdojo.ryanhost.GA.MuPlusOne.GeneticAlgorithm  - Testing candidate
1101010101111111001100000101011100110000100001111111001000001001101101000011100101011000000100000000110110001110
1101010101111111001100000101011100110000100001111111001000001001101101000011100101011000000100000000110110001110
5853 [Thread-2] DEBUG Threadmain  - entering run of Robot Interface
5869 [Thread-2] DEBUG Threadmain  - Send Genome via serial and wait for a response
5881 [Thread-2] DEBUG Threadmain  - fitness is 0.0
1101010101111111001100000101011100110000100001111111001000001001101101000011100101011000000100000000110110001110
1101010101111111001100000101011100110000100001111111001000001001101101000011100101011000000100000000110110001110
10
Output buffer after put
1101010101111111001100000101011100110000100001111111001000001001101101000011100101011000000100000000110110001110

Buffer isn't empty

initialFitness method
1110110101110000001100101100110001001010010101011110001101010010100100111011111000011101110000001110100111001111
16593 [main] DEBUG org.dnsdojo.ryanhost.GA.MuPlusOne.GeneticAlgorithm  - Testing candidate
1110110101110000001100101100110001001010010101011110001101010010100100111011111000011101110000001110100111001111
1110110101110000001100101100110001001010010101011110001101010010100100111011111000011101110000001110100111001111
16944 [Thread-3] DEBUG Threadmain  - entering run of Robot Interface
16953 [Thread-3] DEBUG Threadmain  - Send Genome via serial and wait for a response
16964 [Thread-3] DEBUG Threadmain  - fitness is 0.0
1110110101110000001100101100110001001010010101011110001101010010100100111011111000011101110000001110100111001111
1110110101110000001100101100110001001010010101011110001101010010100100111011111000011101110000001110100111001111
10
Output buffer after put
1110110101110000001100101100110001001010010101011110001101010010100100111011111000011101110000001110100111001111

Buffer isn't empty
parking to wait for <0xab770958> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)