奇怪的死锁(?)

我在使用两个线程的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);
}
但是,程序在某些时候会挂起(当我使用单个线程运行它时不会发生这种情况)。为了调试我的应用程序,我在挂起后使用了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)            - 已锁定&lt; 0x00000000853f2020>(bgp.parser.Entry)           在bgp.parser.Entry.parseTxtFile(Entry.java:141)           在bgp.parser.Entry.run(Entry.java:31)      “Thread-1”prio = 6   tid = 0x0000000006b52800 nid = 0x9390   runnable [0x00000000082ef000]   java.lang.Thread.State:RUNNABLE           在java.util.HashMap.getEntry(未知   资源)           在java.util.HashMap.containsKey(未知   资源)           at bgp.parser.Entry.identifiedLinksHasKey(Entry.java:281)            - 已锁定&lt; 0x00000000853f00e0>(bgp.parser.Entry)           在bgp.parser.Entry.parseTxtFile(Entry.java:134)           在bgp.parser.Entry.run(Entry.java:31) 它接缝两个线程同时访问两个同步函数,这与同步的含义相矛盾。即使我使用对象锁,也会发生相同的情况。虽然线程的状态不是BLOCKED但是RUNNABLE它们表现为阻塞,可能是因为它们同时访问同一个hashmap。 如果有人能解释我为什么会发生这种奇怪的情况,我真的很感激。     
已邀请:
'synchronized'关键字在对象级锁定。即:在一个对象中不能同时运行两个同步方法。 是否有可能从两个单独的线程中调用两个不同的对象? 编辑: 重新访问堆栈跟踪,我越来越相信这确实是这种情况。更改代码如下。
private boolean identifiedLinksHasKey(String linkKey){
       synchronized(Parser) {
            return Parser.identifiedLinks.containsKey(linkKey);
        }
}

private void putToIdentifiedLinks(String key, TreeSet<String> aset){     
    synchronized(Parser) {    
        Parser.identifiedLinks.put(key,aset);
    }
}
我自己没有尝试过这个代码,而且我不能100%确定是否可以使用类(Parser)而不是一个对象来锁定。如果这不起作用,只需选择可从两个线程/实例访问的任何(单个)对象。     
比较这两个: bgp.parser.Entry.putToIdentifiedLinks(Entry.java:297) - 已锁定&lt; 0x00000000853f2020&gt; bgp.parser.Entry.identifiedLinksHasKey(Entry.java:281) - 已锁定&lt; 0x00000000853f00e0&gt; 他们持有不同的锁。
synchronized
关键字锁定对象实例。 (即如果你创建两个物体
Object a=new Object();
Object b=new Object();
,锁定
a
不会影响
b
)     
我怀疑
identifiedLinksHasKey()
putToIdentifiedLinks()
方法是由
bgp.parser.Entry
类的两个不同实例执行的,在这种情况下,
synchronized
将不起作用。     
如果Parser是单例类或Entry类的静态成员,则方法的同步将不起作用,因为它仅保护Entry对象的成员变量。静态成员不受该计划的保护。最好的办法是,将Parser类的identifyLinks成员作为ConcurrentHashMap。     
可能是您将文件作为具有保证唯一身份的对象进行了处理?如果您依赖它,比如说,您希望表示文件的对象在内存中保证全局唯一。它将一直有效,直到违反uniqness。 uniqness中的漏洞可能来自操作系统API。它以Windows而闻名(但很少有来自Unix的人很好理解),创建的文件的文件句柄与通过findFirst / findnext找到并打开的文件的文件句柄不同。 将操作系统中的文件API视为非常远程系统的通信API,不保证原因和后果。如果您创建文件,并不意味着您可以立即找到它,如果您删除文件,这可能意味着您之后可能仍会找到它。等等     

要回复问题请先登录注册