奇怪的死锁(?)

Vas*_*lis 1 java multithreading synchronization deadlock

我在使用两个线程的Java应用程序中遇到了一个非常奇怪的死锁.两个线程都将数据读写到共享散列映射.为了避免同步问题,我使得同步读取和写入数据的函数的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);
}
Run Code Online (Sandbox Code Playgroud)

但是,程序在某些时候会挂起(当我使用单个线程运行它时不会发生这种情况).为了调试我的应用程序,我在挂起后使用了jstack,这给了我以下的线程转储:

"thread-2"prio = 6 tid = 0x0000000006b09800 nid = 0x78fc runnable [0x00000000083ef000]
java.lang.Thread.State:在bgp.parser.Entry的java.util.HashMap.put(未知来源)中的RUNNABLE.putToIdentifiedLinks(Entry.java:297) - 在bgp.parser.Entry.run的bgp.parser.Entry.parseTxtFile(Entry.java:141)中锁定<0x00000000853f2020>(bgp.parser.Entry)(Entry.java:31 )

"Thread-1"prio = 6 tid = 0x0000000006b52800 nid = 0x9390 runnable [0x00000000082ef000]
java.lang.Thread.State:java.util.HashMap.containsKey(未知来源)java.util.HashMap.getEntry(未知来源)的RUNNABLE )在bgp.parser.Entry.identifiedLinksHasKey(Entry.java:281) -在bgp.parser.Entry.parseTxtFile(Entry.java:134)在bgp.parser.Entry.run(Entry.java:31锁定<0x00000000853f00e0>(一个bgp.parser.Entry) )

它接缝两个线程同时访问两个同步函数,这与同步的含义相矛盾.即使我使用对象锁,也会发生相同的情况.虽然线程的状态不是BLOCKED但是RUNNABLE它们表现为阻塞,可能是因为它们同时访问同一个hashmap.

如果有人能解释我为什么会发生这种奇怪的情况,我真的很感激.

J-1*_*DiZ 7

比较这两个:

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();,锁定in a将不会影响b)