Java -- Thread -- Collection -- 6hreadLocal类及应用技巧

JDK1.5提供了ThreadLocal类来方便实现线程范围内的数据共享,它的作用就相当于上一节中的Map。

       每个线程调用全局ThreadLocal对象的set方法,就相当于往其内部的map集合中增加一条记录,key就是各自的线程,value就是各自的set方法传进去的值。

       在线程结束时可以调用ThreadLocal.clear()方法用来更快释放内存,也可以不调用,因为线程结束后也可以自动释放相关的ThreadLocal变量。

       一个ThreadLocal对象只能记录一个线程内部的一个共享变量,需要记录多个共享数据,可以创建多个ThreadLocal对象,或者将这些数据进行封装,将封装后的数据对象存入ThreadLocal对象中。

       将数据对象封装成单例,同时提供线程范围内的共享数据的设置和获取方法,提供已经封装好了的线程范围内的对象实例,使用时只需获取实例对象即可实现数据的线程范围内的共享,因为该对象已经是当前线程范围内的对象了。下边给出张老师的优雅代码:

package cn.itheima;
import java.util.Random;
public class ThreadLocalShareDataDemo
{    /**06. ThreadLocal类及应用技巧
     * 将线程范围内共享数据进行封装,封装到一个单独的数据类中,提供设置获取方法
     * 将该类单例化,提供获取实例对象的方法,获取到的实例对象是已经封装好的当前线程范围内的对象
     */
    public static void main(String[] args)
    {
        for (int i=0; i<2; i++)
        {
            new Thread(
                    new Runnable()
                    {                        
                        public void run()
                        {
                            int data = new Random().nextInt(889);
    System.out.println(Thread.currentThread().getName()+"产生数据:"+data);
                            MyData myData = MyData.getInstance();
                            myData.setAge(data);
                            myData.setName("Name:"+data);
                            new A().get();
                            new B().get();
                        }
                    }).start();
        }
    }
    static class A
    {    //可以直接使用获取到的线程范围内的对象实例调用相应方法
        String name = MyData.getInstance().getName();
        int age = MyData.getInstance().getAge();
        public void get() 
        {
            System.out.println(Thread.currentThread().getName()+"-- AA name:"+name+"...age:"+age);
        }
    }    
    static class B
    {
        //可以直接使用获取到的线程范围内的对象实例调用相应方法
        String name = MyData.getInstance().getName();
        int age = MyData.getInstance().getAge();
        public void get() 
        {
            System.out.println(Thread.currentThread().getName()+"-- BB name:"+name+"...age:"+age);
        }
    }    
    static class MyData
    {
        private String name;
        private int age;
        public String getName()
        {
            return name;
        }
        public void setName(String name)
        {
            this.name = name;
        }
        public int getAge()
        {
            return age;
        }
        public void setAge(int age)
        {
            this.age = age;
        }
        //单例
        private MyData() {};
        //提供获取实例方法
        public static MyData getInstance()
        {
            //从当前线程范围内数据集中获取实例对象
            MyData instance = threadLocal.get();
            if (instance==null)
            {
                instance = new MyData();
                threadLocal.set(instance);
            }
            return instance;
        }
        //将实例对象存入当前线程范围内数据集中
        static ThreadLocal<MyData> threadLocal = new ThreadLocal<MyData>();
    }
}

 

 

 

holder

posted on 2016-04-24 19:44  yeatschen  阅读(144)  评论(0)    收藏  举报

导航