java - 奇怪的死锁(?)

标签 java multithreading synchronization deadlock

我在使用两个线程的 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/

相关文章:

Java 有没有办法初始化类型安全的通用数组?

java - 不支持的功能异常 fetchDmlReturnParams

java - 搜索包含正斜杠的字段的正确 mysql 查询是什么?

java - 应用程序引擎在任务突发期间中止请求错误

c++ - 在单独的线程中为新小部件设置公共(public)父 Qt 小部件

multithreading - 效率问题 - 在并行线程上搜索数组

python - ElasticSearch 更新不是立即的,你如何等待 ElasticSearch 完成更新它的索引?

java - 单例的同步(哈希)映射

.net - .NET ThreadPool 线程在返回池时是否会重置?

synchronization - CPU 中的相关负载重新排序