0

JDK 1.6のドキュメントには、の使用方法に関する例が示されていますLocalThread<T>。ここにコピーして貼り付けます:

たとえば、以下のクラスは、各スレッドにローカルな一意の識別子を生成します。スレッドのIDは、最初に呼び出されたときに割り当てられ、UniqueThreadIdGenerator.getCurrentThreadId()その後の呼び出しでは変更されません。

 import java.util.concurrent.atomic.AtomicInteger; 

 public class UniqueThreadIdGenerator {    
     private static final AtomicInteger uniqueId = new AtomicInteger(0);    
     private static final ThreadLocal <Integer> uniqueNum = 
         new ThreadLocal <Integer> () {
             @Override 
             protected Integer initialValue() {
                 return uniqueId.getAndIncrement();
         }
     };

     public static int getCurrentThreadId() {
         return uniqueId.get();
     }
 } // UniqueThreadIdGenerator

私の問題は:

複数のスレッドが呼び出すUniqueThreadIdGenerator.getCurrentThreadId()場合、初期化がないため、0のみが返されます。このようにすべきではありません:

public static int getCurrentThreadId() {
    return uniqueNum.get();
}

最初の呼び出しの後、変数を初期化します。

4

1 に答える 1

5

はい、そうする必要がありますuniqueNum.get()JDK 7のドキュメントはそれを正しく理解し、より適切な名前を使用します。

import java.util.concurrent.atomic.AtomicInteger;

public class ThreadId {
    // Atomic integer containing the next thread ID to be assigned
    private static final AtomicInteger nextId = new AtomicInteger(0);

    // Thread local variable containing each thread's ID
    private static final ThreadLocal<Integer> threadId =
        new ThreadLocal<Integer>() {
            @Override protected Integer initialValue() {
                return nextId.getAndIncrement();
        }
    };

    // Returns the current thread's unique ID, assigning it if necessary
    public static int get() {
        return threadId.get();
    }
}

ただし、実際には初期化の問題ではありません。単に、間違ったメンバーを完全に使用するだけの問題です。元のコードで多くのコード使用されていたとしても、「現在のスレッドに割り当てられたID」ではなく、常に「次に割り当てられるID」が返されます。uniqueNumgetCurrentThreadId()

于 2011-10-19T19:12:42.920 に答える