我有一个实现Runnable的类。出于日志记录的原因,我想知道用于运行该类的Thread。在那种情况下最好做
public class WebSocketHandle implements Runnable {
private Thread myThread; // access to thread for logging
public void start() {
myThread = new Thread(this);
myThread.start();
}
}
然后在创建这些的方法中,我执行以下操作:
public void newSocket(Socket socket)
{
WebSocketHandle handle = new WebSocketHandle(this, socket,_identity);
_sockets.add(handle);
EventLog.write("Socket assigned for new connection (" + _sockets.size() + ") " + handle.toString() + ". No value received yet yet...", getClass().getName(), "register");
// Start thread listening for data
new Thread(handle).start();
}
或者最好有类似的东西:
public class WebSocketHandle implements Runnable {
private String myThread;
public void setThreadOwner(string threadId) {
myThread = threadId;
}
}
然后它将被用作:
WebSocketHandle handle = new WebSocketHandle();
Thread newThread = new Thread(handle);
newThread.start();
handle.setThreadOwner(handle.toString());
我不禁觉得第二种选择是更好的练习,但写的代码看起来更笨拙?
编辑:回应亚伦的评论:
这是针对Web服务器套接字处理代码,因此Thread将以无限的方式运行。我没有考虑使用ThreadPools,所以这可能是我需要考虑的事情
我记录了WebSocketHandle类中的各种活动(即接收和发送的数据),因此我想将日志记录事件绑定到运行它的Thread实例。为此,我发现最简单的方法是将thread.toString()记录为日志输出的一部分。
答案 0 :(得分:4)
您只需调用Thread.currentThread()
即可获取正在执行代码的线程。
要帮助识别线索,请使用new Thread("some useful name");
[编辑] 您的两种方法都有一些缺点。第一种方法总是创建一个线程,因此你不能在线程池中执行runnable。最终,你会想要这样做。不幸的是,当您发现自己的情况时,您的应用程序将变得非常复杂,并且很难改变。
此外,“线程”对你没什么帮助;它通常与哪个线程启动的东西无关。在查找错误时,您想知道哪一段代码执行了一个方法。因此,将Logger
传递给start()
会更有意义。
那就是说,“访问线程进行日志记录”是什么意思?在start()
中创建的匿名线程包含哪些信息可能对日志记录有用?由于它有一个生成的名称,你仍然不知道谁叫start()
,第一种方法对我来说看起来完全没用。
第二种方法允许你给Runnable
一个名字,但a)它不编译,b)也没有任何意义(没有提到变量名称令人困惑的事实)。 / p>
要获得某类课程,您可以致电getClass().getName()
;使用setter设置实例的类名是没有意义的。所以第二种方法很危险,它违反了DRY principle。
此外,它没有为您提供有用的日志记录信息:它不会告诉您是谁创建了MyClass
的实例,如果您想要MyClass
的记录器,您只需使用这一行:
private Logger log = LoggerFactory.getLogger(getClass());
不需要设置器。
所以我的结论是应该避免这两种方法。