2017-12-28 28 views
-1

자바에서 ThreadLocal 개체의 사용을 테스트하고 싶지만 내 initialValue()가 작동하지 않는 것 같습니다. 그리고 정확히 get()set() 전에 호출하면 예상대로 변수 ID을 반환해야합니다.왜 ThreadLocal의 initialValue()가 작동하지 않습니까?

public class UsageThreadLocal implements Runnable { 
    private AnotherThreadID<Long> var; 

    public UsageThreadLocal(AnotherThreadID<Long> v) { 
     this.var = v; 
    } 

    public void run() { 
     try { 
      print("var getThreadID =" + var.get()); 
      Thread.sleep(200); 
      var.set(Thread.currentThread().getId()); 
      print("var getThreadID =" + var.get()); 
     } catch (InterruptedException x) { 
     } 
    } 

    private static void print(String msg) { 
     String name = Thread.currentThread().getName(); 
     System.out.println(name + ": " + msg); 
    } 

    public static void main(String[] args) { 
     AnotherThreadID<Long> tid = new AnotherThreadID<Long>() { 
      @Override 
      public Long initialValue() { 
       ID = new Long(100); 
       System.out.println("I'm in initialValue()!"); 
       return ID; 
      } 
     }; 
     UsageThreadLocal shared = new UsageThreadLocal(tid); 

     try { 
      Thread threadA = new Thread(shared, "threadA"); 
      threadA.start(); 

      Thread.sleep(50); 

      Thread threadB = new Thread(shared, "threadB"); 
      threadB.start(); 

      Thread.sleep(50); 

      Thread threadC = new Thread(shared, "threadC"); 
      threadC.start(); 
     } catch (InterruptedException x) { 
     } 
    } 
} 

class AnotherThreadID<T> extends ThreadLocal<T> { 
    public T ID; 

    @Override 
    public void set(T newID) { 
     ID = newID; 
    } 

    @Override 
    public T get() { 
     return ID; 
    } 

} 

내 코드의 결과를 실행 :

threadA: var getThreadID =null 
threadB: var getThreadID =null 
threadC: var getThreadID =null 
threadA: var getThreadID =9 
threadB: var getThreadID =10 
threadC: var getThreadID =11 

무엇 내 코드의 문제가 아니면 내가 ThreadLocal의 사용을 오해를 여기에 내 코드?

+0

모든 개체는 자동으로'개체'를 상속하고, 그것을 확장시키지 않아도됩니다 ('extends Object') –

답변

1

문제는 AnotherThreadID의 구현입니다. ThreadLocal은 각 스레드에 대한 값을 유지하는 것입니다. get()set()은 기본적으로 ThreadLocal이 아닙니다.

AnotherThreadID 클래스를 삭제하고 AnotherThreadIDThreadLocal으로 바꿔도 코드는 더 이상 변경하지 않고 작동합니다.

+0

고마워요 @ 케빈 왕. 즉,''get()''또는''set()''을 오버라이드하는 것은 더 복잡한 작업이 필요합니까? – zhanghui

+0

@zhanghui 보통 initialValue()를 구현하면 충분합니다. 그리고 ThreadLocal에서 get()과 set()을 살펴보면 어떻게 작동하는지 더 잘 알 수 있습니다. 솔직히 나는 어떤 경우에 그들이 오버라이드 될 필요가 있는지 보지 못한다. –

+0

''get()''또는''set()''을 "MyThreadLocal"객체에서 원하는 동작을 빌드하는 데 사용하는 기본 방법으로 간주해야한다는 의미입니다. – zhanghui

0

AnotherThreadID는 스레드에 의해 초기화되어야하지만 주 스레드에서 초기화해야합니다. 그리고 하나의 AnotherThreadID 인스턴스 만 있습니다. 사실, 각 스레드에는 인스턴스가 있어야합니다.