多线程篇四:ThreadLocal实现线程范围内变量共享

1.static实现线程范围内变量共享

package com.test.shareData;

import java.util.Random;

/**
 * 多线程范围内的数据共享
 * @author Administrator
 *
 */
public class ThreadScopeShareData {

    private static int data;
    public static void main(String[] args) {
        for(int i=0;i<2;i++){
            new Thread(new Runnable(){
                @Override
                public void run() {
                    data=new Random().nextInt();
                    System.out.println("currentThread:"+Thread.currentThread().getName()+" get data value is:"+data);
                    new A().get();
                    new B().get();
                    /**
                     * 输出:static 变量是内存中共享的,第二个线程的值会覆盖第一个线程的值
                     *  currentThread:Thread-0 get data value is:312589459
                        currentThread:Thread-1 get data value is:312589459
                        A currentThread:Thread-1 get data value is:312589459
                        A currentThread:Thread-0 get data value is:312589459
                        B currentThread:Thread-1 get data value is:312589459
                        B currentThread:Thread-0 get data value is:312589459
                     */
                }
            }).start();
        }
        
    }
    
    static class A{
        public void get(){
            System.out.println("A currentThread:"+Thread.currentThread().getName()+" get data value is:"+data);
        }
    }
    
    static class B{
        public void get(){
            System.out.println("B currentThread:"+Thread.currentThread().getName()+" get data value is:"+data);
        }
    }
}
View Code

currentThread:Thread-0 get data value is:312589459
currentThread:Thread-1 get data value is:312589459
A currentThread:Thread-1 get data value is:312589459
A currentThread:Thread-0 get data value is:312589459
B currentThread:Thread-1 get data value is:312589459
B currentThread:Thread-0 get data value is:312589459

package com.test.shareData;

import java.util.Random;

/***
 * @description 通过ThreadLocal实现,同一个线程范围内,不同的对象中数据共享
 * 注意:一个ThradLocal只能代表一个变量,即只能放一个数据;多个线程范围内都需要共享数据,则需要定义多个ThreadLocal
 * 另外:多个变量共享,同一个线程范围内共享,可通过创建实体对象,将实体对象放到ThreadLocal中
 *
 */
public class ThreadLocalTest1 {
    
    private static ThreadLocal<Integer> x=new ThreadLocal<Integer>();
    public static void main(String[] args) {
        for(int i=0;i<2;i++){
            new Thread(new Runnable(){
                @Override
                public void run() {
                    int data=new Random().nextInt();
                    x.set(data);
                    System.out.println(Thread.currentThread().getName()+" data"+data);
                    MyTreadScopeData1 myTreadScopeData =MyTreadScopeData1.getInstance();
                    myTreadScopeData.setName("chenxiaobing"+data);
                    myTreadScopeData.setAge(data);
                    new A().get();
                    new B().get();
                }
            }).start();
        }
        
    }
    static class A{
        int data=x.get();
        private void get(){
            System.out.println("class A:"+Thread.currentThread().getName()+data);
            MyTreadScopeData1 myTreadScopeData =MyTreadScopeData1.getInstance();
            System.out.println("class A  myThreadLocal:"+Thread.currentThread().getName()+myTreadScopeData.getName());
        }
    }
    
    static class B{
        int data=x.get();
        private void get(){
            System.out.println("class B:"+Thread.currentThread().getName()+data);
            MyTreadScopeData1 myTreadScopeData =MyTreadScopeData1.getInstance();
            System.out.println("class B  myThreadLocal:"+Thread.currentThread().getName()+myTreadScopeData.getName());
        }
    }
}


class MyTreadScopeData1{
    

    private MyTreadScopeData1(){}//私有的构成方法,使其他无法创建实例对象
    
    //1.懒汉、饱汉模式的单例,预先定义一个静态的实例对象
    /*private static MyTreadScopeData1 instance=new MyTreadScopeData1();
    public static MyTreadScopeData1 getInstance(){//定义一个可供其他调用的静态方法
        return instance;
    }*/
    
    //2.饿汉模式的单例,只有在需要时才创建实例对象
    /*private static MyTreadScopeData1 instance=null;
    public static synchronized MyTreadScopeData1 getInstance(){//定义一个可供其他调用的静态方法
        if(null==instance){
            instance =new MyTreadScopeData1();
        }
        return instance;
    }*/

    //3.这里ThreadLocal的使用,类似1/2中的单例模式,只是1/2单例模式,所有线程都会共享MyTreadScopeData1的实例对象
    private static ThreadLocal<MyTreadScopeData1> myThreadLocal=new ThreadLocal<MyTreadScopeData1>();
    
    //不同的线程共享不同的实例对象,不需要使用synchronized
    public static MyTreadScopeData1 getInstance(){
        MyTreadScopeData1 instance=myThreadLocal.get();
        if(null==instance){
            instance =new MyTreadScopeData1();
            myThreadLocal.set(instance);
        }
        return instance;
    }
    
    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;
    }
    
}
View Code

输出:

currentThread:Thread-1 get data value is:139815514
A currentThread:Thread-1 get map:139815514
currentThread:Thread-0 get data value is:-1291672817
A currentThread:Thread-0 get map:-1291672817
B currentThread:Thread-1 get map:139815514
B currentThread:Thread-0 get map:-1291672817

2.ThreadLocal实现线程范围内变量共享

package com.test.shareData;

import java.util.Random;

/***
 * @description 通过ThreadLocal实现,同一个线程范围内,不同的对象中数据共享
 * 注意:一个ThradLocal只能代表一个变量,即只能放一个数据;多个线程范围内都需要共享数据,则需要定义多个ThreadLocal
 * 另外:多个变量共享,同一个线程范围内共享,可通过创建实体对象,将实体对象放到ThreadLocal中
 *
 */
public class ThreadLocalTest {
    
    //1.一个ThradLocal只能代表一个变量,即只能放一个数据;多个线程范围内都需要共享数据,则需要定义多个ThreadLocal
    private static ThreadLocal<Integer> x=new ThreadLocal<Integer>();
    
    //2.多个变量共享(共享name,age),同一个线程范围内共享,可通过创建实体对象,将实体对象放到ThreadLocal中
    private static ThreadLocal<MyTreadScopeData> myThreadLocal=new ThreadLocal<MyTreadScopeData>();
    public static void main(String[] args) {
        for(int i=0;i<2;i++){
            new Thread(new Runnable(){
                @Override
                public void run() {
                    int data=new Random().nextInt();
                    x.set(data);
                    System.out.println(Thread.currentThread().getName()+" data"+data);
                    MyTreadScopeData myTreadScopeData=new MyTreadScopeData();
                    myTreadScopeData.setName("chenxiaobing");
                    myTreadScopeData.setAge(28);
                    myThreadLocal.set(myTreadScopeData);
                    new A().get();
                    new B().get();
                }
            }).start();
        }
        
    }
    static class A{
        int data=x.get();
        private void get(){
            System.out.println("class A:"+Thread.currentThread().getName()+data);
        //    MyTreadScopeData myThread=myThreadLocal.get();
        //    myThread.setAge(30);
        //    myThread.setName("aaaaaaaaaaaaaaa");
            System.out.println("class A  myThreadLocal:"+Thread.currentThread().getName()+myThreadLocal.get().getName());
        }
    }
    
    static class B{
        int data=x.get();
        private void get(){
            System.out.println("class B:"+Thread.currentThread().getName()+data);
        //    MyTreadScopeData myThread=myThreadLocal.get();
        //    myThread.setAge(30);
        //    myThread.setName("bbbbbbbbbbbbbbbb");
            System.out.println("class B  myThreadLocal:"+Thread.currentThread().getName()+myThreadLocal.get().getName());

        }
    }
}


class MyTreadScopeData{
    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;
    }
    
}
View Code

输出:

Thread-0 data1679550355
Thread-1 data387829581
class A:Thread-1387829581
class A myThreadLocal:Thread-1chenxiaobing
class B:Thread-1387829581
class B myThreadLocal:Thread-1chenxiaobing
class A:Thread-01679550355
class A myThreadLocal:Thread-0chenxiaobing
class B:Thread-01679550355
class B myThreadLocal:Thread-0chenxiaobing

单例模式:

package com.test.shareData;

import java.util.Random;

/***
 * @description 通过ThreadLocal实现,同一个线程范围内,不同的对象中数据共享
 * 注意:一个ThradLocal只能代表一个变量,即只能放一个数据;多个线程范围内都需要共享数据,则需要定义多个ThreadLocal
 * 另外:多个变量共享,同一个线程范围内共享,可通过创建实体对象,将实体对象放到ThreadLocal中
 *
 */
public class ThreadLocalTest1 {
    
    private static ThreadLocal<Integer> x=new ThreadLocal<Integer>();
    public static void main(String[] args) {
        for(int i=0;i<2;i++){
            new Thread(new Runnable(){
                @Override
                public void run() {
                    int data=new Random().nextInt();
                    x.set(data);
                    System.out.println(Thread.currentThread().getName()+" data"+data);
                    MyTreadScopeData1 myTreadScopeData =MyTreadScopeData1.getInstance();
                    myTreadScopeData.setName("chenxiaobing"+data);
                    myTreadScopeData.setAge(data);
                    new A().get();
                    new B().get();
                }
            }).start();
        }
        
    }
    static class A{
        int data=x.get();
        private void get(){
            System.out.println("class A:"+Thread.currentThread().getName()+data);
            MyTreadScopeData1 myTreadScopeData =MyTreadScopeData1.getInstance();
            System.out.println("class A  myThreadLocal:"+Thread.currentThread().getName()+myTreadScopeData.getName());
        }
    }
    
    static class B{
        int data=x.get();
        private void get(){
            System.out.println("class B:"+Thread.currentThread().getName()+data);
            MyTreadScopeData1 myTreadScopeData =MyTreadScopeData1.getInstance();
            System.out.println("class B  myThreadLocal:"+Thread.currentThread().getName()+myTreadScopeData.getName());
        }
    }
}


class MyTreadScopeData1{
    

    private MyTreadScopeData1(){}//私有的构成方法,使其他无法创建实例对象
    
    //1.懒汉、饱汉模式的单例,预先定义一个静态的实例对象
    /*private static MyTreadScopeData1 instance=new MyTreadScopeData1();
    public static MyTreadScopeData1 getInstance(){//定义一个可供其他调用的静态方法
        return instance;
    }*/
    
    //2.饿汉模式的单例,只有在需要时才创建实例对象
    /*private static MyTreadScopeData1 instance=null;
    public static synchronized MyTreadScopeData1 getInstance(){//定义一个可供其他调用的静态方法
        if(null==instance){
            instance =new MyTreadScopeData1();
        }
        return instance;
    }*/

    //3.这里ThreadLocal的使用,类似1/2中的单例模式,只是1/2单例模式,所有线程都会共享MyTreadScopeData1的实例对象
    private static ThreadLocal<MyTreadScopeData1> myThreadLocal=new ThreadLocal<MyTreadScopeData1>();
    
    //不同的线程共享不同的实例对象,不需要使用synchronized
    public static MyTreadScopeData1 getInstance(){
        MyTreadScopeData1 instance=myThreadLocal.get();
        if(null==instance){
            instance =new MyTreadScopeData1();
            myThreadLocal.set(instance);
        }
        return instance;
    }
    
    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;
    }
    
}
View Code

输出:

Thread-0 data667513514
class A:Thread-0667513514
class A myThreadLocal:Thread-0chenxiaobing667513514
Thread-1 data-452485471
class A:Thread-1-452485471
class A myThreadLocal:Thread-1chenxiaobing-452485471
class B:Thread-0667513514
class B:Thread-1-452485471
class B myThreadLocal:Thread-1chenxiaobing-452485471
class B myThreadLocal:Thread-0chenxiaobing667513514

原文地址:https://www.cnblogs.com/brant/p/6017407.html