线程不访问同步块

时间:2012-08-13 11:41:09

标签: java multithreading synchronized

我在生产代码中突然出现问题,这是自去年5 - 6年以来没有发生过的。我有一个线程池,最多可以生成64个线程,所有64个线程读取一些数据并将其放在一个公共Map中进行进一步处理。

读取由来自特定源的所有线程完成,我已经验证数据确实是从源读取的,但是,一个特定的批处理没有被放入Map

这是一个代码段(由于机密性问题,无法输入整个代码):

try {
   <read the data>
    .
    .
    <do processing>
    .
    .
    synchronized(glock) { //glock is a class attribute, Object glock = new Object[];
     map.put(<data that was read>);
     log.debug("bla bla bla")
    }
} catch(Throwable e) { 
     log.error("error") 
  }
  finally {
    log.debug("done")
 }

问题:特定线程没有进入同步块,没有放入地图,不打印"bla bla bla",不打印"error"但打印"done" }。

我已经验证了所有内容......代码中没有任何变化,这个问题立即出现了。问题是,我不能放任何额外的日志,因为它是生产代码而没有让所有客户同意,但这是最后一部分。

有没有人遇到类似的问题,或者对此有所了解?正在读取的数据量巨大,有6000条记录,每条记录至少有30-40列数据。

提前致谢。

编辑:抓取Throwable而不是Exception

2 个答案:

答案 0 :(得分:3)

从您向我们展示的内容看来,

synchronized(glock){}

将数据放到地图上时抛出异常,而不是打印“bla bla bla” 打印“已完成”,因为它位于finally的{​​{1}}块中。

答案 1 :(得分:2)

您的代码有99%的可能性存在问题。这意味着synchronized块中的代码会引发异常,但您没有看到它。

通常的罪魁祸首是:

  • 清空异常的catch块(可以在代码中的其他位置)
  • catch块中记录器的异常日志配置,例如,将异常写入不同的日志文件
  • 由于某种原因,不会按顺序写入日志消息(因此ERROR行不在您期望的位置)
  • 某些异常情况(如内存不足)加上弹性代码可防止写入日志消息。地图可能需要大量的内存。
  • log不是标准的Java记录器,而是其他东西。

您在VM中发现错误或存在硬件问题的可能性很小(<1%)。如果您可以重复获得相同的结果,那么可能不是硬件问题。

如果其他一切都失败了,您需要在生产中调试问题。当然,您的客户会反对;那时候,你会让他们决定哪一个对他们更重要:有些人规定你不得调试代码或修复bug。