zoukankan      html  css  js  c++  java
  • 多线程篇四: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

  • 相关阅读:
    服务器建设问题
    JDBC --反射(二)
    Cookies
    http和https区别
    springboot常用注解
    线程池
    悲观锁和乐观锁
    java高并发下的数据安全
    idea解决mybatis逆向工程
    spring Cloud
  • 原文地址:https://www.cnblogs.com/brant/p/6017407.html
Copyright © 2011-2022 走看看