简体   繁体   English

线程无法访问同步块

[英]A thread does not access synchronized block

I have a sudden issue in Production code which was not happening since the last 5-6 years. 我在生产代码中突然遇到了一个问题,这是最近5-6年以来从未发生过的。 I have a Thread Pool that spawns a maximum of 64 threads, and all 64 threads read some data and put it in a common Map for further processing. 我有一个线程池,最多可产生64个线程,并且所有64个线程都读取一些数据并将其放在通用Map以进行进一步处理。

The read is done by all threads from a specific source, and I have verified that the data is indeed getting read from the source, however, one particular batch is not getting put in the Map . 读取是由来自特定源的所有线程完成的,并且我已验证确实从源中读取了数据,但是,没有将特定批处理放入Map

Here is a code snippet (cannot put whole code due to confidentiality issues): 这是一个代码段(由于机密性问题,无法放入完整的代码):

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")
 }

ISSUE: A particular thread does not go into the synchronized block, does not put into the map, does not print "bla bla bla" , does not print "error" but it prints "done" . 问题:特定线程未进入同步块,未放入映射,未打印"bla bla bla" ,不打印"error"但打印了"done"

I have verified everything...nothing has changed in the code, this issue has appeared immediately from nowhere. 我已经验证了所有内容...代码中没有任何变化,这个问题立即从无处出现。 The problem is, I cannot put any additional logs since it is production code without getting all clients agree, but that is the last part. 问题是,我不能放置任何其他日志,因为它是未经所有客户同意的生产代码。但这是最后一部分。

Has anyone faced a similar issue, or know anything about it? 有没有人遇到过类似的问题,或者对此一无所知? The data being read is huge, 6000 records and each record having a minimum 0f 30-40 columns of data. 读取的数据量巨大,有6000条记录,每条记录至少具有0f 30-40列数据。

Thanks in advance. 提前致谢。

EDIT: Catching Throwable and not Exception 编辑:捕获Throwable而不是Exception

From what you showed us it seems, that 从您向我们展示的内容来看,

synchronized(glock){}

throws an exception while putting the data unto the map, not printing the "bla bla bla". 在将数据放到地图上而不是打印“ bla bla bla”时引发异常。
"done" is printed because it in the finally block of the try . 打印“ done”是因为它在tryfinally一块中。

There is a 99% chance that something is wrong with your code. 您的代码有99%的可能性出了点问题。 This means the code in the synchronized block throws an exception but you don't see it. 这意味着synchronized块中的代码将引发异常,但是您看不到它。

The usual culprits are: 常见的罪魁祸首是:

  • Empty catch block which swallows exceptions (can be elsewhere in the code) 空的catch块会吞下异常(可以在代码的其他地方)
  • Unusual log config for the logger in the catch block which, for example, writes exceptions into a different log file catch块中记录器的异常日志配置,例如,将异常写入另一个日志文件
  • Log messages aren't written in order for some reason (so the ERROR line is not where you expect it) 由于某种原因,日志消息未按顺序写入(因此,ERROR行不在您期望的位置)
  • Some unusual condition (like out of memory) plus resilient code prevents writing of the log messages. 某些异常情况(例如内存不足)加上有弹性的代码阻止了日志消息的写入。 Maps can need surprising amounts of memory. 地图可能需要惊人的内存量。
  • log isn't a standard Java logger but something else. log不是标准的Java记录器,而是其他东西。

There is a small (< 1%) chance that you found a bug in your VM or there is a hardware issue. 您发现虚拟机中存在错误或硬件问题的可能性很小(<1%)。 If you can get the same results repeatedly, it's probably not a hardware issue. 如果您可以重复获得相同的结果,则可能不是硬件问题。

If everything else fails, you will need to debug the issue in production. 如果其他所有操作均失败,则需要在生产中调试问题。 Of course, your client will object; 当然,您的客户会反对。 at that time, you will let them decide which is more important to them: Some rule that you mustn't debug the code or fixing the bug. 到那时,您将让他们决定哪个对他们更重要:某些规则,您不得调试代码或修复错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM