zoukankan      html  css  js  c++  java
  • Java 学习笔记之 实例变量非线程安全

    实例变量非线程安全:

    如果多个线程共同访问1个对象中的实例变量,则可能出现“非线程安全”问题。

    public class UnSafeHasSelfPrivateNum {
        private int num = 0;
        public void addI(String username) {
            try {
                if (username.equals("a")){
                    num = 100;
                    System.out.println("a set over!");
                    Thread.sleep(2000);
                } else {
                    num = 200;
                    System.out.println("b set over!");
                }
                System.out.println(username + " num = " + num);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public class UnSafeHasSelfPrivateNumThreadA extends Thread{
        private UnSafeHasSelfPrivateNum numRef;
    
        public UnSafeHasSelfPrivateNumThreadA(UnSafeHasSelfPrivateNum numRef) {
            this.numRef = numRef;
        }
    
        @Override
        public void run() {
            super.run();
            numRef.addI("a");
        }
    }
    
    public class UnSafeHasSelfPrivateNumThreadB extends Thread {
        private UnSafeHasSelfPrivateNum numRef;
    
        public UnSafeHasSelfPrivateNumThreadB(UnSafeHasSelfPrivateNum numRef) {
            this.numRef = numRef;
        }
    
        @Override
        public void run() {
            super.run();
            numRef.addI("b");
        }
    }
    
    public class ThreadRunMain {
        public static void main(String[] args) {
            testUnSafeHasSelfPrivateNumThread();
        }
    
        public static void testUnSafeHasSelfPrivateNumThread(){
            UnSafeHasSelfPrivateNum numRef = new UnSafeHasSelfPrivateNum();
            UnSafeHasSelfPrivateNumThreadA athread = new UnSafeHasSelfPrivateNumThreadA(numRef);
            athread.start();
            UnSafeHasSelfPrivateNumThreadB bthread = new UnSafeHasSelfPrivateNumThreadB(numRef);
            bthread.start();
        }
    }

    运行结果:

    a的值本应该是100,却变成了200. 用synchronized关键字解决问题:

    public class UnSafeHasSelfPrivateNum {
        private int num = 0;
        synchronized public void addI(String username) {
            try {
                if (username.equals("a")){
                    num = 100;
                    System.out.println("a set over!");
                    Thread.sleep(2000);
                } else {
                    num = 200;
                    System.out.println("b set over!");
                }
                System.out.println(username + " num = " + num);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    运行结果:

    在两个线程访问同一个对象中的同步方法时是线程安全的,先执行a,在执行b。

  • 相关阅读:
    Java实现LeetCode_0028_ImplementStrStr
    Java实现图形化计算器
    Java实现图形化计算器
    Java实现图形化计算器
    Java实现图形化计算器
    Java实现LeetCode_0026_RemoveDuplicatesFromSortedArray
    Java实现LeetCode_0026_RemoveDuplicatesFromSortedArray
    Java实现LeetCode_0026_RemoveDuplicatesFromSortedArray
    Java实现LeetCode_0026_RemoveDuplicatesFromSortedArray
    STS开发环境搭建与配置
  • 原文地址:https://www.cnblogs.com/AK47Sonic/p/7705584.html
Copyright © 2011-2022 走看看