我在生产代码中突然出现问题,这是自去年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
答案 0 :(得分:3)
从您向我们展示的内容看来,
synchronized(glock){}
将数据放到地图上时抛出异常,而不是打印“bla bla bla”
打印“已完成”,因为它位于finally
的{{1}}块中。
答案 1 :(得分:2)
您的代码有99%的可能性存在问题。这意味着synchronized
块中的代码会引发异常,但您没有看到它。
通常的罪魁祸首是:
catch
块(可以在代码中的其他位置)catch
块中记录器的异常日志配置,例如,将异常写入不同的日志文件log
不是标准的Java记录器,而是其他东西。您在VM中发现错误或存在硬件问题的可能性很小(<1%)。如果您可以重复获得相同的结果,那么可能不是硬件问题。
如果其他一切都失败了,您需要在生产中调试问题。当然,您的客户会反对;那时候,你会让他们决定哪一个对他们更重要:有些人规定你不得调试代码或修复bug。