对ThreadLocal的思考

    ThreadLocal 直译过来是 '本地线程',这个理解是不正确的。来看一个案例。

  1.0 案例

    先是一个接口

public interface Sequence {
    int getNumber();
}

实现类

public class SequenceA implements Sequence{
    static int i = 0;
    public int getNumber() {
       return i++;
    }

    public static void main(String[] args){
        SequenceA sequenceA = new SequenceA();
        new MyThread(sequenceA).start();
        new MyThread(sequenceA).start();
        new MyThread(sequenceA).start();
    }
}

//线程类

public class MyThread extends Thread {
    private Sequence sequence;

    public MyThread(Sequence sequence){
        this.sequence = sequence;
    }

    public void run() {
        for(int i=0;i<4;i++){
            System.out.println(Thread.currentThread().getName()+"--"+sequence.getNumber());
        }
    }
}

运行结果
Thread-0--0
Thread-0--1
Thread-0--2
Thread-0--3
Thread-1--4
Thread-1--5
Thread-1--6
Thread-1--7
Thread-2--8
Thread-2--9
Thread-2--10
Thread-2--11

Process finished with exit code 0
 

因为 

static int i = 0;

是静态的  是所有线程所共享的,所以会出现以上结果,那么我希望每个线程都有独立的  i  呢? 

这时候ThreadLocal 派上用场了,

稍微改造了一下

public class SequenceA implements Sequence{

    private static ThreadLocal<Integer> contaner = new ThreadLocal<Integer>(){
        @Override
        protected Integer initialValue() {
            return 0;
        }
    };

    public int getNumber(){
        contaner.set(contaner.get()+1);
        return contaner.get();
    }


    public static void main(String[] args){
        SequenceA sequenceA = new SequenceA();
        new MyThread(sequenceA).start();
        new MyThread(sequenceA).start();
        new MyThread(sequenceA).start();
    }
}

输出结果:

Thread-0--1
Thread-0--2
Thread-0--3
Thread-0--4
Thread-1--1
Thread-1--2
Thread-1--3
Thread-1--4
Thread-2--1
Thread-2--2
Thread-2--3
Thread-2--4

 

这才是我要的结果嘛,可是为什么 明明是 static的变量 却 每个线程都有了一份,,其实ThreadLocal其实相当于一个容器,它为每个线程 保存了 一个副本

那么 我们有必要来了解下ThreadLocal是怎么实现的  还有为什么我们要实现 

它的   initialValue   方法
protected T initialValue() {
    return null;
}

这是它的源码   方式是protected 那么 它就是提示我们去 现实它,

以下是它的源码 可以看出来 它里面封装了 一个Map 容器 来实现 

public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings("unchecked")
            T result = (T)e.value;
            return result;
        }
    }
    return setInitialValue();
}

有兴趣可以看看它的源码

 

转载于:https://my.oschina.net/u/3394890/blog/1512162

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值