首页 > 技术文章 > ThreadLocal实现线程范围的共享变量

lyajs 2016-07-03 21:51 原文

一、如何理解线程范围内共享数据

1、static int num=0;

2、线程1访问num变量,并设置为num=2;线程2访问num变量,并设置为num=3;

3、当线程1中对象A、B、C 在访问线程1中的num变量的时候,就不是它本身设置的值了,如何才能使线程1访问它本身设置的数据呢?

 

public class ShareData {
    private static double num=0;
    public static void main(String[] args) {
        //同时存在2个线程
        for(int i=0;i<2;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    //每个线程改变num的数据
                    num=new Random().nextDouble();
                    System.out.println(Thread.currentThread().getName()+" has a put num:"+num);
                    //分别调用A、B的对象
                    new A().get();
                    new B().get();
                }
            }).start();
        }
    }
    //A对象  输出 当前线程中 num 的数据
    static class A{
        public void get(){
            System.out.println(Thread.currentThread().getName()+" has a  num---A:"+num);
            
        }
    }
    //B对象 输出 当前线程中 num 的数据
    static class B{
        public void get(){
            System.out.println(Thread.currentThread().getName()+" has a num---B:"+num);
            
        }
    }
}

结果分析:

二、使用Map集合实现线程范围内共享数据

1、private static Map<Thread,Double> map=new HashMap<Thread,Double>();

   通过map集合,来维护每个线程中独自的变量。

public class ThreadScopeSharenum  {
    //全局共享变量 num
    private static double num=0;
    //把Thread作为关键字,设置num的值作为值put到map集合中
    private static Map<Thread,Double> map=new HashMap<Thread,Double>();
    public static void main(String[] args) {
        //维护两个线程
        for(int i=0;i<2;i++){
            new Thread(new Runnable() {
        
                @Override
                public void run() {
                    // 设置num的值,并保存到 currentThread
                    double num=new Random().nextDouble();
                    map.put(Thread.currentThread(), num);
                    System.out.println(Thread.currentThread().getName()+" has a put num:"+num);
                    //A 、B对象通过 currentThread 来获取值
                    new A().get();
                    new B().get();
                }
            }).start();
        }
    }
    //A对象  输出 当前线程中 num 的数据
        static class A{
            public void get(){
                System.out.println(Thread.currentThread().getName()+" has a  num---A:"+map.get(Thread.currentThread()));
                
            }
        }
        //B对象 输出 当前线程中 num 的数据
        static class B{
            public void get(){
                System.out.println(Thread.currentThread().getName()+" has a num---B:"+map.get(Thread.currentThread()));
                
            }
        }
}

结果分析:

三、ThreadLocal实现线程范围的共享变量(1个

  1. new ThreadLocal<T>(); //保证一个T类型的变量,在线程范围内正确的共享。
  2. public void set(T value);//内容维护了一个map集合,key默认为当前线程。
  3. public T get();//取出当前线程,变量的值。
import java.util.HashMap;
import java.util.Map;
import java.util.Random;


public class ThreadScopeSharenum  {
    //全局共享变量 num
    private static double num=0;
    //把Thread作为关键字,设置num的值作为值put到map集合中
    private static ThreadLocal<Double> map=new ThreadLocal<Double>();
    public static void main(String[] args) {
        //维护两个线程
        for(int i=0;i<2;i++){
            new Thread(new Runnable() {
        
                @Override
                public void run() {
                    // 设置num的值,并保存到 currentThread
                    double num=new Random().nextDouble();
                    map.set(num);
                    System.out.println(Thread.currentThread().getName()+" has a put num:"+num);
                    //A 、B对象通过 currentThread 来获取值
                    new A().get();
                    new B().get();
                }
            }).start();
        }
    }
    //A对象  输出 当前线程中 num 的数据
        static class A{
            public void get(){
                System.out.println(Thread.currentThread().getName()+" has a  num---A:"+map.get());
                
            }
        }
        //B对象 输出 当前线程中 num 的数据
        static class B{
            public void get(){
                System.out.println(Thread.currentThread().getName()+" has a num---B:"+map.get());
                
            }
        }
}

四、如何通过ThreadLocal实现线程范围内多个共享变量

 

推荐阅读