字符串键不会从HashMap中删除

问题描述:

我有一个数据库,其中存储了url和他们的md5代码。我需要检查来自一组url的链接是否已经存在于db中。我有以下一段代码,它在多个线程中运行。每个胎面特定MD5关键,这是URL的MD5的前三个数字:字符串键不会从HashMap中删除

String[] urls = new String[linksMap.size()]; 
String[] md5s = new String[linksMap.size()]; 
boolean expectingMittcom = false; 
boolean hadMittcom = false; 
int i = 0; 
for (String url : linksMap.keySet()) { 
    urls[i] = url; 
    if (url.equals("http://mittcom.com/")) { 
    expectingMittcom = true; 
    } 
    md5s[i++] = linksMap.get(url).variationMd5; 
} 

int offset = 0; 
while (offset < urls.length) { 

    Array arMd5 = pqm.getConnection().createArrayOf("text", 
       Arrays.copyOfRange(md5s, offset, Math.min(offset + MAX_NUM, 
       urls.length))); 
    Array arUrl = pqm.getConnection().createArrayOf("text", 
       Arrays.copyOfRange(urls, 
       offset, Math.min(offset + MAX_NUM, urls.length))); 

    PreparedStatement ps = pqm.getConnection().prepareStatement(
         "select url from links.links_" + key 
         + " where md5=any(?) and url=any(?)"); 

    ps.setArray(1, arMd5); 
    ps.setArray(2, arUrl); 
    ResultSet rs = ps.executeQuery(); 

    while (rs.next()) { 
    String url = rs.getString(1); 
    boolean printDebug = false; 
    if (url.equals("http://mittcom.com/")) { 
     hadMittcom = true; 
     printDebug = true; 
    } 
    LinkVariation r = linksMap.remove(url); 
    if (printDebug) { 
     logger.info("Link variation: " + r); 
    } 
    if (r != null) { 
     Map<String, String[]> linksMapOriginal = 
      linksByMD5MapOriginal.get(r.original[INDEX_MD5].substring(0, 3)); 
     if (printDebug) { 
     logger.info("will try to fliter out [" 
        + r.original[INDEX_URL] + "]"); 
     } 
     String[] remove = linksMapOriginal.remove(r.original[INDEX_URL]); 
     if (remove != null) { 
     if (printDebug) { 
      logger.info("Filtered mittcom"); 
      filtered.incrementAndGet(); 
      checkStillHere(); 
     } 
     } else { 
     if (printDebug) { 
      logger.info("Did not filter mittcom"); 
     } 
     } 
    } 
    } 

    rs.close(); 

    ps.close(); 

    offset += MAX_NUM; 
} 
if (expectingMittcom) { 
    if (hadMittcom) { 
    logger.info("was expecting mittcom and found"); 
    } else { 
    logger.info("was expecting mittcom but didn't find"); 
    } 
} 

的问题是,URL“http://mittcom.com”(和其他一些东西,我只是调试此特别是)还停留在linksByMD5MapOriginal hashMap。我可以在日志文件中看到它已被删除和过滤,但线程完成运行后仍然存在!我不明白它会发生什么!我会怀疑问题与不同的hashCode等,但密钥是纯String,应该没有这样的问题。我真的很困惑。

我检查一下所有类似的胎面后完成运行:

for (Map.Entry<String, Map<String, String[]>> entrySet : linksByMD5MapOriginal.entrySet()) { 
     String key = entrySet.getKey(); 
     Map<String, String[]> value = entrySet.getValue(); 
     if (value.containsKey("http://mittcom.com/")) { 
      logger.info("STILL HERE in " + key); 
     } 
    } 

HashMap的是initilaized如下:

protected Map<String, Map<String, String[]>> linksByMD5MapOriginal = new TreeMap<>(); 

...

linksByMD5MapOriginal.put(md5Key, linksByKeyMap = Collections.synchronizedMap(new TreeMap<String, String[]>())); 

这里TreeMap的是为了更容易的调试,它不必订购。底层hashMap是同步的,并发修改它应该没有问题。线程运行时,什么都没有添加到hashMap中。另一个奇怪的是,我不能使用远程调试器(程序在远程服务器上运行),因为如果我尝试这样做,程序最终会挂起,所以我强制使用日志打印输出进行调试。但这不是我在这里要求的一般问题。问题是,过滤的URL仍然挂在hashMap!

对不起,如果我的问题似乎不清楚,我会更新我的帖子,如果有任何后续问题。任何帮助将不胜感激。

UPD:记录打印输出:

[2017-10-04 07:25:57,580] [INFO ] [CheckUnique] [Thread-46229] Link variation: [email protected] 
[2017-10-04 07:25:57,580] [INFO ] [CheckUnique] [Thread-46229] will try to fliter out [http://www.mittcom.com/] 
[2017-10-04 07:25:57,580] [INFO ] [CheckUnique] [Thread-46229] Filtered mittcom 
[2017-10-04 07:25:57,580] [INFO ] [CheckUnique] [Thread-46229] Link variation: null 
[2017-10-04 07:25:57,580] [INFO ] [CheckUnique] [Thread-46229] Link variation: null 
[2017-10-04 07:25:57,580] [INFO ] [CheckUnique] [Thread-46229] Link variation: null 
[2017-10-04 07:25:57,580] [INFO ] [CheckUnique] [Thread-46229] Link variation: null 
[2017-10-04 07:25:57,580] [INFO ] [CheckUnique] [Thread-46229] Link variation: null 
[2017-10-04 07:25:57,580] [INFO ] [CheckUnique] [Thread-46229] Link variation: null 
[2017-10-04 07:25:57,580] [INFO ] [CheckUnique] [Thread-46229] Link variation: null 
[2017-10-04 07:25:57,580] [INFO ] [CheckUnique] [Thread-46229] Link variation: null 
[2017-10-04 07:25:57,580] [INFO ] [CheckUnique] [Thread-46229] Link variation: null 
[2017-10-04 07:25:57,580] [INFO ] [CheckUnique] [Thread-46229] was expecting mittcom and found 

...

[2017-10-04 07:46:35,337] [INFO ] [CheckUnique] [main] STILL HERE in cd2 
+2

'''''linkByMD5MapOriginal.remove()'从来不会在你显示的任何代码中被调用,所以我没有看到它没有任何理由不在那里。 – Compass

+4

等待这个问题的代码太多了。你能否提供一个[mcve]来代替? –

+0

请格式化您的代码,一目了然,而不是滚动左右 – JFPicard

我固定的错误和它无关,这一段代码是什么地方。简而言之,链接变异检查机制被打破。我可以删除这个问题吗?

+0

是的,您可以 - 请花费更多时间在下次将问题减少到[mcve],因为您经常会发现问题而无需提问。另外,作为一个评论,这会更好,因为它实际上不是问题的答案。 –