2010-06-21 31 views
5

Tôi đã đọc về ThreadLocal, cố gắng hiểu cách nó hoạt động và tại sao chúng ta cần nó.ThreadLocal pondering (Hoặc: Mặt trời có phải là javadoc không?)

Cho đến nay những gì tôi đã có thể học như sau:

  1. lớp ThreadLocal cho phép tổ chức 1 thể hiện của một đối tượng ở cấp chủ đề
  2. Các ví dụ được tạo ra bằng cách ghi đè initialValue()
  3. các ví dụ thực sự được lưu trữ trong các ví dụ sử dụng each thread's HashMap
  4. Một cảm giác chung can be found here

Tất cả dường như tốt đẹp, cho đến khi tôi đã cố gắng để chạy các ví dụ từ javadoc, mã được cung cấp như sau:

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 

Nếu tôi hiểu mã này một cách chính xác, gọi getCurrentThreadId() nên trả lại tự động tăng lên số chủ đề đúng , nó trả về 0 cho tôi. LUÔN LUÔN 0, mà không xem xét có bao nhiêu chủ đề tôi đã bắt đầu.

Để làm việc này cho tôi, tôi đã phải thay đổi getCurrentThreadId() để đọc

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

Trong trường hợp mà tôi đang nhận được giá trị chính xác.

Mã của tôi được cung cấp bên dưới, tôi thiếu gì? (Nó không phải là javadoc thực sự là sai, phải không ??)

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 

Output:

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 

tái bút: Mã nhận xét OT hoặc đến điểm được hoan nghênh trong các bình luận.

Trả lời

9

Các javadocs sai.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6475885

Java 7's javadoc bao gồm

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

tuyệt vời, lỗi này là gần 4 tuổi. Phải mất 4 năm để sửa lỗi đánh máy của hướng dẫn sử dụng html trên máy chủ web. Trong thời gian trung bình có 20 bản cập nhật. Tuyệt vời .... –

+2

@Peter Không thể thay đổi đặc điểm kỹ thuật trong bản phát hành cập nhật. Bạn có thể thấy rằng lỗi đã được thực sự cố định năm trước. –

+0

Cảm ơn thông báo. –

Các vấn đề liên quan