Thread.setName(name)警告

时间:2011-04-03 22:06:28

标签: java multithreading thread-safety threadpool

我有一个使用套接字的多线程客户端服务器应用程序。找到新连接后,使用新的Executors线程池将进一步执行转移到新线程。

我想在该客户端的所有日志记录语句中记录客户端ID。问题是我不想修改方法签名只是为了传递客户端ID。

我想到的解决方案是:

  1. 使用ThreadLocal保存客户端值。
  2. 在run()中,我可以使用Thread.currentThread()将客户端ID设置为Thread.setName(clientId);
  3. 首先应该有效。但我喜欢第二种选择,因为 一个。我可以从调试器中找到客户端ID 湾记录器库可以配置为显示线程名称。因此,日志语句不需要进行任何更改,它也适用于库中的记录器。

    除了javadoc中提到的那些之外,使用thread.setName()的注意事项是什么?它如何影响性能?调用thread.setName()的峰值频率约为每秒200次,平均值约为每秒0.3次。

3 个答案:

答案 0 :(得分:3)

如果您使用Log4j,则有一种特定的机制可以处理这种类型的日志记录模式,在两个类org.apache.log4j.NDCorg.apache.log4j.MDC之间进行拆分('嵌套和映射的诊断上下文')。

浏览NDC vs MDC - Which one should I use?,了解哪种方法适合您的特定情况。

这是另一个链接,它更详细地描述了MDC的使用:Build Flexible Logs With log4j - O'Reilly Media

请注意,底层存储机制MDC / NDC使用(我相信)无论如何都是ThreadLocal。

答案 1 :(得分:2)

  

除了javadoc中提到的那些之外,使用thread.setName()的注意事项是什么?它如何影响性能?调用thread.setName()的峰值频率约为每秒200次,平均值约为每秒0.3次。

性能不应该是一个重要问题。 Thread.setName()执行安全检查,然后复制/设置属性。安全检查应该很便宜,除非您的代码是在安全沙箱中运行的特权代码,该安全沙箱禁止对Thread.setName()方法进行非特权调用。

我能想到的另一个警告是,如果你试图调试线程行为,那么线程名称一直在变化可能会让人感到困惑。例如看着线程转储等等。

答案 2 :(得分:1)

我在开发软件(printserver)中使用第二种方法,但线程运行时很长,因此“setName()”不会增加处理延迟。 记录阶段非常好,显示线程名称。

我认为“setName()”在两种情况下是个问题:

  1. 非常短暂;
  2. 更多具有不同身份的演员使用的线程(但这不是你的背景,或者不是?)。
  3. 再见。