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

私は仕方がないのですが、2番目のオプションがより良い練習であると感じますが、書くコードは不器用に見えますか?

編集:アーロンのコメントに応えて:

  1. これはWebサーバーのソケット処理コード用であるため、スレッドは無期限に実行されます。私はThreadPoolsの使用を検討していなかったので、おそらくそれを検討する必要があります

  2. WebSocketHandleクラスでさまざまなアクティビティ(つまり、送受信されたデータ)をログに記録するので、ログイベントを実行中のThreadインスタンスに関連付けたいと思いました。そのための最も簡単な方法は、ログ出力の一部としてthread.toString()をログに記録することでした。

4

1 に答える 1

4

を呼び出すだけThread.currentThread()で、現在コードを実行しているスレッドを取得できます。

スレッドの識別に役立てるために、new Thread("some useful name");

[編集]どちらのアプローチにもいくつかの欠点があります。最初のアプローチでは常にスレッドが作成されるため、たとえばスレッドプールでランナブルを実行することはできません。そして最終的に、あなたはそれをしたいと思うでしょう。残念ながら、あなたがそうしていることに気付いたとき、あなたのアプリケーションは非常に複雑になり、変更するのは難しいでしょう。

また、「スレッド」はあまり役に立ちません。通常、どのスレッドが何かを開始したかは関係ありません。バグを探すときは、どのコードがメソッドを実行したかを知りたいと思います。したがって、にを渡す方が理にかなっていLoggerますstart()

そうは言っても、「ロギングのためのスレッドへのアクセス」とはどういう意味ですか?で作成された匿名スレッドにはstart()、ロギングに役立つ可能性のあるどのような情報が含まれていますか?生成された名前があり、誰が電話をかけたかはまだわからないためstart()、最初のアプローチは私にはまったく役に立たないように見えます。

2番目のアプローチではRunnable、名前を付けることができますが、a)コンパイルされず、b)意味がありません(変数名が混乱しているという事実は言及していません)。

何かのクラスを取得するには、getClass().getName();を呼び出すことができます。セッターを使用してインスタンスのクラス名を設定しても意味がありません。したがって、2番目のアプローチは危険なほど混乱を招き、DRYの原則に違反します。

また、ロギングに役立つ情報はあまり提供されません。誰がのインスタンスを作成したMyClassかはわかりません。のロガーが必要な場合はMyClass、次の行を使用できます。

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

セッターは必要ありません。

したがって、私の結論は、両方のアプローチを避けるべきであるということです。

于 2012-11-14T08:10:28.170 に答える