import java.util.HashMap;import java.util.Map;import java.util.Random;

public class ThreadScopeShareData {

/**     *  多个线程访问同一个成员变量,因该是每一个线程拿到的变量是不同的     *  比如银行的转账     *  张三对李四     *  王五对赵六     *  如果成员变量不和线程绑定那么王五就可能在转账时操作张三的钱     *  如下程序因该是每个getData都要从自己的线程拿到自己的数据     *  然而实际情况并非如此*/

//    public static void main(String[] args) {////        for(int i=0;i<9;i++){//            new Thread(new Runnable(){//                @Override//                public void run() {//                    int data = new Random().nextInt();//                    System.out.println(Thread.currentThread().getName()+" has put data of " + data);//                    new A().getData();//                    new B().getData();//                }//                //            }).start();//        }//        //    }////    static class A{//        void getData(){//            System.out.println("A thread from "+Thread.currentThread().getName()+" get data of " + data);//        }//    }//    //    static class B{//        void getData(){//            System.out.println("B thread from "+Thread.currentThread().getName()+" get data of " + data);//            //        }//    }

/*     * 我们知道一个线程就对应一个数据,这就相当于map的key和value     * 把每个线程和对应的值填入一个map     * 下面就是一种解决方法*///    private static Map<Thread, Integer> dataMap = new HashMap<Thread, Integer>();//    public static void main(String[] args) {////        for(int i=0;i<9;i++){//            new Thread(new Runnable(){//                @Override//                public void run() {//                    int data = new Random().nextInt();//                    dataMap.put(Thread.currentThread(),data);//                    System.out.println(Thread.currentThread().getName()+" has put data of " + data);//                    new A().getData();//                    new B().getData();//                }//                //            }).start();//        }//        //    }////    static class A{//        void getData(){//            int data = dataMap.get(Thread.currentThread());//            System.out.println("A thread from "+Thread.currentThread().getName()+" get data of " + data);//        }//    }//    //    static class B{//        void getData(){//            int data = dataMap.get(Thread.currentThread());//            System.out.println("B thread from "+Thread.currentThread().getName()+" get data of " + data);//            //        }//    }

//    /*//     * java也提供了一个类来控制线程和变量之间的绑定:ThreadLocal//     * ThreadLocal就相当于上例的map//     *///    

//    private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();//    public static void main(String[] args) {////        for(int i=0;i<9;i++){//            new Thread(new Runnable(){//                @Override//                public void run() {//                    int data = new Random().nextInt();////调用threadLocal.set();参数是要保存的数字//                    threadLocal.set(data);//                    System.out.println(Thread.currentThread().getName()+" has put data of " + data);//                    new A().getData();//                    new B().getData();//                }//                //            }).start();//        }//        //    }////    static class A{//        void getData(){////threadLocal.get()不用指定当前线程,他代表的就是当前线程//            int data = threadLocal.get();//            System.out.println("A thread from "+Thread.currentThread().getName()+" get data of " + data);//        }//    }//    //    static class B{//        void getData(){////threadLocal.get()不用指定当前线程,他代表的就是当前线程//            int data = threadLocal.get();//            System.out.println("B thread from "+Thread.currentThread().getName()+" get data of " + data);//            //        }//    }//    //    /*//     * 总结:一个threadLocal代表一个变量,故其中只能放一个数据,如果有两个变量要线程共享//     * 则要定义两个ThreadLocal对象,如果有很多的变量要共享,就可以考虑把这些变量封装//     * 然后在ThreadLocal中存储这个对象//     * 下面示例是多个变量//     */

/*     * 一个线程和多个变量之间的绑定*///    //    private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();//    private static ThreadLocal<MyThreadScopeData> myThreadLocal = new ThreadLocal<MyThreadScopeData>();//    public static void main(String[] args) {////        for(int i=0;i<9;i++){//            new Thread(new Runnable(){//                @Override//                public void run() {//                    int data = new Random().nextInt();//                    threadLocal.set(data);//                    System.out.println(Thread.currentThread().getName()+" has put data of " + data);//                    //////                    MyThreadScopeData myData = new MyThreadScopeData();//                    myData.setName("name" + data);//                    myData.setAge(data);//                    myThreadLocal.set(myData);//                    //                    new A().getData();//                    new B().getData();//                }//                //            }).start();//        }//        //    }////    static class A{//        void getData(){//            int data = threadLocal.get();//            System.out.println("A thread from "+Thread.currentThread().getName()+" get data " + data);//            //            MyThreadScopeData myData = myThreadLocal.get();//            System.out.println("A thread from "+Thread.currentThread().getName()+" get data " + myData.getAge() + " , " +myData.getAge());//        }//    }//    //    static class B{//        void getData(){//            int data = threadLocal.get();//            System.out.println("B thread from "+Thread.currentThread().getName()+" get data " + data);//            //            MyThreadScopeData myData = myThreadLocal.get();//            System.out.println("B thread from "+Thread.currentThread().getName()+" get data " + myData.getAge() + " , " +myData.getAge());//            //        }//    }//    //    /*//     * 首先定义一个类封装数据//     *///    static class MyThreadScopeData{//        //        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;//        }//    }

//一种更为优雅的实现方式,可以隐藏ThreadLocal    private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();public static void main(String[] args) {

for(int i=0;i<9;i++){new Thread(new Runnable(){                @Overridepublic void run() {int data = new Random().nextInt();                    threadLocal.set(data);                    System.out.println(Thread.currentThread().getName()+" has put data of " + data);

                    MyThreadScopeData.getInstance().setName("name is "+data);                    MyThreadScopeData.getInstance().setAge(data);

new A().getData();new B().getData();                }

            }).start();        }

    }

static class A{void getData(){int data = threadLocal.get();            System.out.println("A thread from "+Thread.currentThread().getName()+" get data " + data);

            MyThreadScopeData myData = MyThreadScopeData.getInstance();            System.out.println("A thread from "+Thread.currentThread().getName()+" get data " + myData.getAge() + " , " +myData.getAge());        }    }

static class B{void getData(){int data = threadLocal.get();            System.out.println("B thread from "+Thread.currentThread().getName()+" get data " + data);

            MyThreadScopeData myData = MyThreadScopeData.getInstance();            System.out.println("B thread from "+Thread.currentThread().getName()+" get data " + myData.getAge() + " , " +myData.getAge());

        }    }

/*     * 实现这个类的单例*/static class MyThreadScopeData{/*饱汉模式创建单例        private MyThreadScopeData(){}        private static MyThreadScopeData instance = new MyThreadScopeData();        public synchronized MyThreadScopeData getInstance(){            return instance;        }*/

/* 饥汉模式创建单例        private MyThreadScopeData(){}        private static MyThreadScopeData instance = null;        public synchronized MyThreadScopeData getInstance(){            if(instance == null){                instance = new MyThreadScopeData();            }            return instance;        }*/

//将ThreadLocal放在了单例的实现里,外部就不用了解内部的实现,外部的调用自然就是与线程有关的实例        private MyThreadScopeData(){}//        private static MyThreadScopeData instance = null;        private static ThreadLocal<MyThreadScopeData> local = new ThreadLocal<MyThreadScopeData>();public static /*synchronized就可以不用了*/ MyThreadScopeData getInstance(){            MyThreadScopeData instance= local.get();if(instance == null){                instance = new MyThreadScopeData();                local.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;        }    }}

转载于:https://www.cnblogs.com/huidaoli/articles/3602827.html

线程之成员变量的线程共享相关推荐

  1. Spring MVC 成员变量 request 线程安全问题的讨论

    2019独角兽企业重金招聘Python工程师标准>>> 作者:wangxinxi 最近有人问我,Spring MVC Controller的成员变量@Resource private ...

  2. 每个线程只对一个数据操作就不会出现线程安全问题-------------成员变量,用来计算累加的和...

    package charpter12; public class Processor implements Runnable { private int count; // 成员变量,用来计算累加的和 ...

  3. (四)多线程说学逗唱:线程险恶,变量和线程安全不得不防

    (一)多线程说学逗唱:关于线程那不得不说的二三事 (二)多线程说学逗唱:新手村偶遇Thread类 (三)多线程说学逗唱:村口的老R头是个扫地僧(Runnable) (五)多线程说学逗唱:打铁还需自身硬 ...

  4. java 线程---成员变量与局部变量

    关于成员变量与局部变量: 如果一个变量是成员变量,那么多个线程对同一个对象的成员变量进行操作时,他们对该成员变量是彼此影响的(也就是说一个线程对成员变量的改变会影响到另一个线程) . 如果一个变量是局 ...

  5. Java多线程编程系列-实例变量和线程安全

    导语   上面说到了多线程的简单实现,编写了几个入门的小例子,这里我们来研究一下关于实例变量和线程安全的问题.在自定义的线程类中的实例变量针对其他线程可以有共享和不共享之分,下多个线程之间进行交互的时 ...

  6. Jmeter跨线程组调用变量

    1.正则表达式提取变量值 2.添加后置管理器 BeanShell PostProcessor,使用函数助手或直接按照格式输入 3.其它线程组调用变量 4.执行结果 5.注意:由于线程组是同时运行的,所 ...

  7. 别翻了,成员变量和局部变量在多线程中的使用,看这篇就够了

    一. 成员变量和局部变量的区别 在类中的位置不同 成员变量:在类中方法外面 局部变量:在方法或者代码块中,或者方法的声明上(即在参数列表中) 在内存中的位置不同 成员变量:在堆中(方法区中静态区),成 ...

  8. 线程之线程共享成员变量的几种情况

    public class ThreadScopeMultiShareData { /** * 多线程之间的共享数据的方式*/ /* * 如果每个线程执行的代码一样,可以使用同一个runnable对象, ...

  9. 如何在MFC线程中使用控件的成员变量和函数

    比如说,在ListBox里我添加了一个CString类型的成员变量m_str,我想用m_str.GetCount或m_str.GetText之类的方法,但这些在线程中就不能用了. 使用控件的成员变量和 ...

最新文章

  1. Samtools安装与使用
  2. Java_异常_03_ java.lang.NoClassDefFoundError: org/apache/commons/pool/KeyedObjectPoolFactory
  3. 画蛇添足之error of activesync over usb link to pc
  4. 邵阳学院计算机科学与技术专业分最低,邵阳学院在湖南各专业录取最低分/最低位次...
  5. 简单实用的铁道部12306.cn网站自动化登录
  6. 是否同一棵二叉搜索树
  7. 梁鑫:美股交易架构实践
  8. 随笔--四个月培训小结
  9. python3.8版本支持flask-sqlalchey包吗_python3中使用flask_sqlalchemy的几个问题
  10. hyper运算符_25个特殊操作符(special operator)
  11. stream().map().collect()用法
  12. 看到这个数据库设计,我终于明白了我和其他软测人的差距
  13. Sourcetree使用 - git图形化工具(三)
  14. 大学学习路线规划建议贴
  15. R统计-PCA/PCoA/db-RDA/NMDS/CA/CCA/DCA等排序分析教程
  16. sop流程图模板_SOP模板-标准操作流程编写程序.doc
  17. python 庖丁科技pdflux的表格解析(精度很高)
  18. linux下 scp 和 ssh 命令
  19. ShaderGUI的学习
  20. 大数据技术背景介绍(开号篇)

热门文章

  1. GO语言学习之路20
  2. Apache OpenNLP提供的文档
  3. SpringBoot整合JDBC数据库操作第二弹-配置基本数据库连接源
  4. rsync通过服务同步、linux日志、screen工具
  5. angular2系列之动画-路由转场动画
  6. laravel 模型事件几种用法
  7. 开源人工智能技术将改变一切
  8. nginx优化--突破十万并发
  9. vmware的原理和影子页表
  10. oracle 10G表空间创建的步骤