ThreadLocal 笔记

synchronized 同步的机制可以解决多线程并发问题,这种解决方案下,多个线程访问到的都是同一份变量的内容。为了防止在多线程访问的过程中,可能会出现的并发错误。不得不对多个线程的访问进行同步,这样也就意味着,多个线程必须先后对变量的值进行访问或者修改,这是一种以延长访问时间换取线程安全性的策略。

ThreadLocal类为每一个线程都维护了自己独有的变量拷贝。每个线程都拥有了自己独立的一个变量,竞争条件被彻底消除了,那就没有任何必要对这些线程进行同步,它们也能最大限度的由CPU调度,并发执行。由于每个线程在访问该变量时,读取和修改的,都是自己独有的那一份变量拷贝,变量被彻底封闭在每个访问的线程中,并发错误出现的可能也完全消除了。这是一种以空间来换取线程安全性的策略

ThreadLocal适用于资源共享但不需要维护状态的情况,也就是一个线程对资源的修改,不影响另一个线程的运行。

ThreadLocal类接口说明:

  • void set(Object value)                            
    • 设置当前线程的线程局部变量的值。
  • public Object get()             
    • 返回当前线程所对应的线程局部变量。
  • protected Object initialValue()          
    • 返回该线程局部变量的初始值,该方法为了让子类覆盖而设计的。
    • 这个方法在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。
    • ThreadLocal中的缺省实现直接返回一个null。
  • public void remove()                       
    • 将当前线程局部变量的值删除,目的是为了加快内存回收的速度,减少内存的占用。

每个Thread都有自己独立的ThreadLocalMap对象,用来存放各自独立的对象集合。

在ThreadLocalMap中是以ThreadLocal作为key存储的,所以一个ThreadLocal代表一个隔离变量。

我们无法直接操纵ThreadLocalMap对象,只能通过ThreadLocal对象用来维护ThreadLocalMap中的变量。

示意图:

ThreadLocal示例

package org.apollo.demo01.demo;


public class ThreadLocalDemo {
    
    static class Countor{
        
        ThreadLocal<Integer> threadLocal1=new ThreadLocal<Integer>(){
            protected Integer initialValue() {
                return 0;
            };
        };
        /**
         * 往ThreadLocalMap中放入Integer用来计数
         */
        public void add(){
            Integer i=threadLocal1.get();
            i++;
            threadLocal1.set(i);
        }
        public void print(){
            Integer i=threadLocal1.get();
            System.out.println(i);
        }
    }
    public static void main(String[] args) {
        
        Runnable runnable=new Runnable() {
            
            Countor countor=new Countor();
            public void run() {
                for(int i=0;i<10;i++){
                    //多个线程共享countor变量,但不共享计数,计数器会为每个线程单独计数
                    countor.add();
                    countor.print();
                }
            }
        };
        for(int i=0;i<3;i++){
            Thread t=new Thread(runnable);
            t.start();
        }
        
    }
}

 

posted @ 2014-02-10 14:43  _流年  阅读(249)  评论(0编辑  收藏  举报