日期:2014-05-20  浏览次数:20699 次

ThreadLocal 主线程获取值问题
Java code

package net.xinxin.test;


public class testThreadLocal {
    protected BankAccount account;
    public testThreadLocal(BankAccount account)
    {
        this.account = account;
    }
    private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>(){
        public Integer initialValue(){
            return 0;
        }
    };
    private ThreadLocal<Integer> accountNum = new ThreadLocal<Integer>(){
        public Integer initialValue(){
            return account.getBalance();
        }
    };
    
    public int getNextNum(){
        seqNum.set(seqNum.get()+1);
        return seqNum.get();
    }
    private int getAccountNum()
    {
        accountNum.set(accountNum.get()+10);
        return accountNum.get();
    }
    
    private static class TestClient extends Thread{
        private testThreadLocal ttl;
        public TestClient(testThreadLocal ttl)
        {
            this.ttl=ttl;
        }
        public void run(){
            for(int i=0;i<3;i++){
                                ttl.getAccountNum();
                System.out.println("thread["+Thread.currentThread().getName()+"] sn["+ttl.getNextNum()+"]");//注释编号1:若在这里打印accountNum.get(),值是期望的
            }
        }
    }
    public static void main(String[] args)throws Exception{
        BankAccount a = new BankAccount(1,100);
        testThreadLocal ttl = new testThreadLocal(a);
        TestClient t1 = new TestClient(ttl);
        TestClient t2 = new TestClient(ttl);
        TestClient t3 = new TestClient(ttl);
        t1.start();
        t2.start();
        t3.start();
        t1.join();
        t2.join();
        t3.join();
        System.out.println(ttl.accountNum.get());//注释编号2:这里打印仅有第一次结果 
    }
}



q1:执行程序后,主线程等待t1 t2 t3先完成,最后执行注释编号2的打印语句,可此时ttl这个对象的值仅被改变了一次。照理来说被传入之后ttl.accountNum的值被set的是ThreadLocal所创建的副本, 那么请问如何才能在主线程正确获取它的值?
q2:ttl.sn也是被ThreadLocal为每个线程所创建的副本,那么如何做到让sn做到连续 而不是t1 t2 t3 都有sn为1 2 3的情况?

------解决方案--------------------
q1: 输出的是 a的初始化值100,应该没错。LZ觉得应该是多少?
BankAccount a = new BankAccount(1,100);

q1: 对,没有共享变量了,每个线程一份自己的数据。