我在使用两个线程的 Java 应用程序中遇到了一个非常奇怪的死锁。两个线程都读取数据并将数据写入共享的 HashMap 。为了避免同步问题,我将读写数据的函数同步到 hashmap 中:
private synchronized boolean identifiedLinksHasKey(String linkKey){
return Parser.identifiedLinks.containsKey(linkKey);
}
private synchronized void putToIdentifiedLinks(String key, TreeSet<String> aset){
Parser.identifiedLinks.put(key,aset);
}
但是,程序有时会挂起(当我用单线程运行它时不会发生)。为了调试我的应用程序,我在它挂起后使用了 jstack,这给了我以下线程转储:
"Thread-2" prio=6 tid=0x0000000006b09800 nid=0x78fc runnable [0x00000000083ef000 ]
java.lang.Thread.State: RUNNABLE at java.util.HashMap.put(Unknown Source) at bgp.parser.Entry.putToIdentifiedLinks(Entry.java:297) - locked <0x00000000853f2020> (a bgp.parser.Entry) at bgp.parser.Entry.parseTxtFile(Entry.java:141) at bgp.parser.Entry.run(Entry.java:31)"Thread-1" prio=6 tid=0x0000000006b52800 nid=0x9390 runnable [0x00000000082ef000 ]
java.lang.Thread.State: RUNNABLE at java.util.HashMap.getEntry(Unknown Source) at java.util.HashMap.containsKey(Unknown Source) at bgp.parser.Entry.identifiedLinksHasKey(Entry.java:281) - locked <0x00000000853f00e0> (a bgp.parser.Entry) at bgp.parser.Entry.parseTxtFile(Entry.java:134) at bgp.parser.Entry.run(Entry.java:31)
似乎两个线程同时访问两个同步函数,这与同步的含义相矛盾。即使我使用对象锁也会发生同样的情况。虽然线程的状态不是 BLOCKED 而是 RUNNABLE,但它们表现得像阻塞,可能是因为它们同时访问同一个 hashmap。
如果有人能向我解释为什么会发生这种奇怪的情况,我将不胜感激。
最佳答案
比较这两个:
bgp.parser.Entry.putToIdentifiedLinks(Entry.java:297) - locked <0x00000000853f2020>
bgp.parser.Entry.identifiedLinksHasKey(Entry.java:281) - locked <0x00000000853f00e0>
他们持有不同的锁。
synchronized
关键字锁定对象实例。 (即,如果您创建两个对象 Object a=new Object();
Object b=new Object();
,锁定在 a
中'影响 b
)
关于java - 奇怪的死锁(?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4118424/