为什么我的ThreadLocal的initialValue()没有工作?

时间:2017-12-28 09:15:13

标签: java multithreading initialization thread-local

我想在java中测试ThreadLocal对象的用法,但似乎我的initialValue()不起作用。我在get()之前呼叫set(),它应该按预期返回100的变量ID。这是我的代码:

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的用法?

2 个答案:

答案 0 :(得分:1)

问题在于AnotherThreadID的实施。 ThreadLocal是为每个帖子保留一个值,您覆盖get()set()基本上不再是ThreadLocal

您可以删除AnotherThreadID课程,并将AnotherThreadID替换为ThreadLocal,然后您的代码无需进一步更改即可使用。

答案 1 :(得分:0)

AnotherThreadID应该是其线程的init,但是你在主线程中初始化它。而且你只有一个AnotherThreadID实例。实际上,每个线程都应该有一个实例。