2010-06-21 14 views
5

He estado leyendo acerca de ThreadLocal, tratando de entender cómo funciona y por qué lo necesitamos.reflexión de ThreadLocal (¿o es incorrecto el javadoc de sun?)

Hasta ahora lo que he sido capaz de aprender es la siguiente:

  1. clase ThreadLocal permite mantener 1 instancia de un objeto en el nivel de rosca
  2. La instancia se crea reemplazando initialValue()
  3. la instancia se almacena en el ejemplo de uso each thread's HashMap
  4. un sentido común can be found here

Todo parecía estar bien, hasta que intentó ejecutar el ejemplo de la javadoc, se proporciona el código de la siguiente manera:

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 

Si entiendo este código correctamente, llamando GetCurrentThreadId() debería devolver el número de hilos automático incrementado correcta , por desgracia, devuelve 0 para mí. SIEMPRE 0, sin considerar cuántos hilos he comenzado.

Para conseguir este trabajo para mí que tenía que cambiar GetCurrentThreadId() para leer

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

En cuyo caso, que estoy recibiendo valores correctos.

Mi código se proporciona a continuación, ¿qué es lo que me falta? (No es que el Javadoc es realmente mal, no ??)

package org.vekslers; 

import java.util.concurrent.TimeUnit; 
import java.util.concurrent.atomic.AtomicInteger; 

public class UniqueThreadIdGenerator extends Thread { 

    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 uniqueNum.get(); 
    } 




    ////////////////////////////////////////////////// 
    // Testing code... 
    ////////////////////////////////////////////////// 
    private static volatile boolean halt = false; 

    public UniqueThreadIdGenerator(String threadName) { 
     super(threadName); 
    } 

    @Override 
    public void run() { 
     System.out.println(Thread.currentThread() + " PREHALT " + getCurrentThreadId()); 
     while(!halt) 
      try { 
       TimeUnit.SECONDS.sleep(1); 
      } catch (InterruptedException e) { 
      } 
     System.out.println(Thread.currentThread() + " POSTHALT " + getCurrentThreadId()); 
    } 

    public static void main(String[] args) throws InterruptedException { 
     Thread t1 = new UniqueThreadIdGenerator("t1"); 
     Thread t2 = new UniqueThreadIdGenerator("t2"); 
     Thread t3 = new UniqueThreadIdGenerator("t3"); 
     Thread t4 = new UniqueThreadIdGenerator("t4"); 

     t3.start(); 
     t1.start(); 
     t2.start(); 
     t4.start(); 

     TimeUnit.SECONDS.sleep(10); 
     halt = true; 
    } 
} // UniqueThreadIdGenerator 

Salida:

Thread[t3,5,main] PREHALT 0 
Thread[t1,5,main] PREHALT 1 
Thread[t2,5,main] PREHALT 2 
Thread[t4,5,main] PREHALT 3 
Thread[t4,5,main] POSTHALT 3 
Thread[t2,5,main] POSTHALT 2 
Thread[t1,5,main] POSTHALT 1 
Thread[t3,5,main] POSTHALT 0 

P. S. Comentarios del código OT o al punto son bienvenidos en los comentarios.

Respuesta

9

Los javadocs son incorrectos.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6475885

Java 7's javadoc incluye

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(); 
    } 
} 
+0

increíble, este error es casi 4 años de edad. Se necesitan 4 años para corregir un error tipográfico del manual html en un servidor web. Mientras tanto, hubo 20 lanzamientos de actualización. Increíble .... –

+2

@ Peter La especificación no se puede cambiar en una versión de actualización. Puedes ver que el error fue arreglado hace años. –

+0

Gracias por el aviso. –

Cuestiones relacionadas