ThreadLocal类

来源:互联网 发布:客户数据库管理软件 编辑:程序博客网 时间:2024/05/17 08:05

ThreadLocal
不是解决资源共享的问题,而是用来提供线程内的局部变量,这样每个线程都自己管理自己的局部变量,别的线程操作的数据不会对我产生影响,互不影响,ThreadLocal是自己管理自己的资源,相当于封装在Thread内部了,供线程自己管理

ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。
使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
从线程的角度看,目标变量就象是线程的本地变量。

public class ThreadLocal<T> {     public ThreadLocal();    public T get();    protected T initialValue();    public void remove();    public void set(T);     static class ThreadLocalMap {        ...    }   }

void set(Object value)设置当前线程的线程局部变量的值。
public Object get()该方法返回当前线程所对应的线程局部变量。
public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,
但它可以加快内存回收的速度。
protected Object initialValue()返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,
在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null

ThreadLocal用来解决对象共享访问:
1。每个线程中都有一个自己的ThreadLocalMap类对象,可以将线程自己的对象保持到其中,隔离了多个线程对数据的访问冲突,线程可以正确的访问到自己的对象。
2。将一个共用的ThreadLocal静态实例作为key,将不同对象的引用保存到不同线程的ThreadLocalMap(用于存储每一个线程的变量副本,ThreadLocalMap中元素的键为线程对象,而值对应线程的变量副本)中,
然后在线程执行的各处通过这个静态ThreadLocal实例的get()方法取得自己线程保存的那个对象,避免了将这个对象作为参数传递的麻烦
3、ThreadLocal使得各线程能够保持各自独立的一个对象,并不是通过ThreadLocal.set()来实现的,而是通过每个线程中的new对象的操作来创建的对象,每个线程创建一个,不是什么对象的拷贝或副本

ThreadLocal易出现内存泄漏,避免内存泄露:
1、ThreadLocal要设为static静态的
2、在线程不使用它的值时手动remove掉该ThreadLocal的值

示例:

public class ThreadLocalTest {    //通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值      private static ThreadLocal<Integer> idNum = new ThreadLocal<Integer>(){ //ThreadLocal<T> 泛型类,每个线程都能保持一个整型的idNum对象        @Override        protected Integer initialValue() {            return 0;        }    };    static class RunnableT implements Runnable{        private int num;        public MyRunnable(int num){            this.num = num;        }        @Override        public void run() {            idNum.set(num);            System.out.println("num: "+idNum.get());        }    }    public static void main(String[] args){        new Thread(new RunnableT(1));        new Thread(new RunnableT(2));    }}
原创粉丝点击