java线程中的ThreadLocal

ThreadLocal是java中提供的一种维护变量的工具,尤其是一些需要维护的共享的静态变量。当多个线程访问同一个对象实例时,由于对象的引用特性,不同线程对该对象的增改都会影响其他线程的使用。这里就牵扯到多线程的共享与资源争夺问题。

ThreadLocal为每个访问线程提供了一个私有的变量存储空间,原理就是,依靠ThreadLocal实现了一个同步的map集合。集合中,键值对分别为线程的名字和访问的资源,是一对多的关系。
实例:
主函数:

  public class LoggerTest {
    public static void main(String[] args) throws Exception{
        new TestThread("Thread1").start();//三个相同的线程
        new TestThread("Thread2").start();//访问同一个静态变量
        new TestThread("Thread3").start();//为了互不影响的操纵这个静态变量
    }
}

公共线程:

class TestThread extends  Thread{
    public TestThread(String name) throws IOException {
        super(name);
    }
    @Override
    public void run() {
        for (int i=0;i<10;i++){
                SimpleThreadLogger.log(getName() +":message ");  //三个线程调用同一个静态函数《==》访问公共资源
            try{
                Thread.sleep(1000);
            }catch (Exception e){
                SimpleThreadLogger.log(e.toString());
            }
        }
    }
}

公共变量:

public class SimpleThreadLogger {
    //三个线程都拥有这个静态变量,为了让他们不会互相影响
    private static final java.lang.ThreadLocal<Logger> threadLocal1 =
            new java.lang.ThreadLocal<Logger>();
    //输出信息

    public static  void log(String msg){
        getThreadLogger().log(Level.INFO, msg);
    }
    //根据线程取得专属Logger
    private static Logger getThreadLogger(){
        Logger logger = threadLocal1.get();
        if(logger == null){
            try{
                logger = Logger.getLogger(
                        Thread.currentThread().getName()
                );
                //Logger 默认在控制台输出
                //加入一个文件输出的handler
                //它会输出xml的记录文件
                logger.addHandler(
                        new FileHandler(
                                Thread.currentThread().getName() + ".log"));
            }catch (IOException e){}
            threadLocal1.set(logger);
        }
        return logger;
    }
}

下面给出ThreadLocal实现的一个例子:

public class ThreadLocal<T>{
    //一个带锁的同步集合
    private Map<Thread,T> storage =
            Collections.synchronizedMap(new HashMap<Thread, T>());

    public T get(){
        Thread current = Thread.currentThread();
        T t = storage.get(current);

        if(t==null && !storage.containsKey(current)){
            t = initialValue();
            storage.put(current,t);
        }
        return  t;
    }

    public void set(T t){
        storage.put(Thread.currentThread(), t);
    }

    public  T initialValue(){
        return  null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值