0

我有一个实现 Runnable 的类。出于日志记录的原因,我想知道用于运行该类的线程。在这种情况下,最好这样做

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());

我不禁觉得第二种选择是更好的做法,但编写的代码似乎更笨拙??

编辑:回应亚伦的评论:

  1. 这是针对 Web 服务器套接字处理代码的,因此线程将无限期地运行。我没有考虑过使用 ThreadPools 所以也许这是我需要考虑的事情

  2. 我在 WebSocketHandle 类中记录各种活动(即接收和发送的数据),因此我想将日志记录事件与它正在运行的 Thread 实例联系起来。为此,我发现最简单的方法是将 thread.toString() 记录为日志输出的一部分。

4

1 回答 1

4

您可以简单地调用Thread.currentThread()以获取正在执行代码的线程。

为了帮助识别线程,请使用new Thread("some useful name");

[编辑]你的两种方法都有一些缺点。第一种方法总是创建一个线程,因此您不能在线程池中执行可运行文件。最终,你会想要这样做。不幸的是,当您发现您这样做时,您的应用程序将变得非常复杂并且很难更改。

“线程”也对您没有多大帮助;哪个线程开始某事通常无关紧要。在查找错误时,您想知道哪段代码执行了某个方法。所以将 a 传递Loggerstart().

也就是说,“访问线程以进行日志记录”是什么意思?创建的匿名线程start()包含哪些可能对日志记录有用的信息?由于它有一个生成的名称,而您仍然不知道谁打电话start()给我,所以第一种方法对我来说完全没用。

第二种方法允许您给出Runnablea 名称,但 a) 它不能编译并且 b) 也没有任何意义(更不用说变量名称令人困惑的事实)。

要获取某物的类别,您可以调用getClass().getName(); 使用 setter 设置实例的类名是没有意义的。所以第二种方法很容易混淆,它违反了DRY 原则

此外,它没有为您提供太多有用的日志信息:它没有告诉您谁创建了 的实例,MyClass如果您想要一个 logger MyClass,您可以简单地使用这一行:

private Logger log = LoggerFactory.getLogger(getClass());

不需要二传手。

所以我的结论是这两种方法都应该避免。

于 2012-11-14T08:10:28.170 回答