2

スレッドに一意の ID を設定する可能性はありますか? 多くの異なるマシンでスレッドが作成される分散システムでは (RMI などによって)?

ログメッセージを作成するために必要です。私の調査から、log4j mdc/ndc を使用して実行できることがわかっていますが、シングル スレッドでのみ実行できます。私の問題は、スレッドの作成時にIDを設定する必要があることです(異なるJVMのスレッドに同じIDを使用するが、同じリクエストに対して)

分散システムは初めてです。

4

4 に答える 4

2

グローバルに一意のリクエスト ID が必要な場合は、カウンターで prcoessAndName (以下を参照) を使用し、これをメッセージ/リクエストと共に渡し、これを使用してスレッド名を設定できます。

public void processRequest(String uniqueRequestId, args) {
    Thread t = Thread.currrentThread();
    String tName = t.getName();
    try {
        t.setName("Processing " + uniqueRequestId);
        // preform process request
    } finally {
        t.setName(tName);
    }
}

このようにして、スレッドが実行されているスレッド/マシンに関係なく、スレッドの名前にリクエスト ID が含まれます。ログにスレッドの名前を含めると、それが含まれます。


を使用してスレッドの名前を設定できます

String processAndHost = ManagementFactory.getRuntimeMXBean().getName()

これにわかりやすい名前またはカウンターを追加できます。

このようにして、すべてのスレッド名が一意になります。

a) 一意のホスト名を持っている場合、この名前はグローバルに一意であると想定できます。b) プロセスが再起動されないため、同じホスト上で同じプロセス ID を持つ 2 つのクライアントが (異なる時間に) 重大なリスクになることがよくあります。問題。

これをローカルで一意の ID と組み合わせて、分散型の一意の ID を取得できます。

ExecutorService service = Executors.newCachedThreadPool(new ThreadFactory() {
    final String processName = ManagementFactory.getRuntimeMXBean().getName();
    final AtomicLong counter = new AtomicLong();
    @Override
    public Thread newThread(Runnable r) {
        String name = processName+"-"+counter.getAndIncrement();
        return new Thread(r, name);
    }
});
for(int i=0;i<10;i++)
    service.submit(new Runnable() {
        @Override
        public void run() {
            System.out.println("["+Thread.currentThread().getName()+"] - Hello World.");
            Thread.yield();
        }
    });
service.shutdown();

版画

[9480@myhost-0] - Hello World.
[9480@myhost-3] - Hello World.
[9480@myhost-2] - Hello World.
[9480@myhost-1] - Hello World.
[9480@myhost-5] - Hello World.
[9480@myhost-4] - Hello World.
[9480@myhost-6] - Hello World.
[9480@myhost-7] - Hello World.
[9480@myhost-0] - Hello World.
[9480@myhost-7] - Hello World.
于 2012-07-26T07:56:23.493 に答える
2

スレッドに名前を付けることができます ( class のさまざまなコンストラクターを参照してくださいjava.lang.Thread)。たとえば、コンピューター名と一意の番号で構成される各スレッドの名前を作成できます。

たとえば を使用してスレッドを作成している場合は、独自の実装をExecutorService渡してスレッドを作成し、その名前を設定できます。ExecutorServicejava.util.concurrent.ThreadFactory

于 2012-07-26T07:56:45.197 に答える
1

許容できないスレッド作成のオーバーヘッドがないわけではありません。

存在さえしない実装不可能なグローバルスレッドIDではなく、リクエストIDまたはセッションIDでログを記録する必要があります。

クリックトラックのロギングについて調査する必要があると思います。

于 2012-07-26T08:19:46.710 に答える
0

スレッドの名前を設定できますが、スレッドの ID を設定/変更することはできません スレッドの getId メソッドの Java ドキュメントから

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#getId ()

「このスレッドの識別子を返します。スレッド ID は、このスレッドが作成されたときに生成された正の長い数値です。スレッド ID は一意であり、その存続期間中は変更されません。スレッドが終了すると、このスレッド ID が再利用される可能性があります。」

于 2012-07-26T07:58:43.787 に答える