我有一个使用套接字的多线程客户端服务器应用程序。找到新连接后,使用新的Executors线程池将进一步执行转移到新线程。
我想在该客户端的所有日志记录语句中记录客户端ID。问题是我不想修改方法签名只是为了传递客户端ID。
我想到的解决方案是:
首先应该有效。但我喜欢第二种选择,因为 一个。我可以从调试器中找到客户端ID 湾记录器库可以配置为显示线程名称。因此,日志语句不需要进行任何更改,它也适用于库中的记录器。
除了javadoc中提到的那些之外,使用thread.setName()的注意事项是什么?它如何影响性能?调用thread.setName()的峰值频率约为每秒200次,平均值约为每秒0.3次。
答案 0 :(得分:3)
如果您使用Log4j,则有一种特定的机制可以处理这种类型的日志记录模式,在两个类org.apache.log4j.NDC和org.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()”在两种情况下是个问题:
再见。