zoukankan      html  css  js  c++  java
  • Android-Java-解决(多线程存钱案例)的安全隐患-synchronized

    多线程存钱案例:

    package android.java.thread10;
    
    /**
     * 两个储户,到同一个银行存钱,每个人存了3次,一次1000000.00元
     * 1.描述银行
     * 2.描述储户任务
     * 3.分析这个多线程是否存在安全隐患
     */
    
    /**
     * 1.描述银行
     */
    class Bank {
    
        private double moneyAsset;
    
        public void addMoney(double moneyAsset) {
            this.moneyAsset += moneyAsset;
            System.out.println(Thread.currentThread().getName() + "存入" + this.moneyAsset + "元");
        }
    
    }
    
    /**
     * 2.描述储户任务
     */
    class Customer implements Runnable {
    
        private Bank bank = new Bank();
    
        @Override
        public void run() {
            for (int i = 0; i < 3; i++) {
                bank.addMoney(1000000.00);
            }
        }
    }
    
    public class BankTest {
    
        public static void main(String[] args) {
            // 定义执行的任务
            Runnable customer = new Customer();
    
            // 线程执行>>>定义执行的任务
            new Thread(customer).start();
            new Thread(customer).start();
        }
    
    }

    执行结果,每次结果不同是由于CPU随机执行某个线程造成的

    但是出现这种情况,就是出现了安全问题,Thread-1存入2000000.0元,Thread-0存入2000000.0元:

    Thread-1存入2000000.0元
    Thread-0存入2000000.0元
    Thread-1存入3000000.0元
    Thread-0存入4000000.0元
    Thread-1存入5000000.0元
    Thread-0存入6000000.0元

    对于为什么会出现安全问题,可以看Android-多线程安全问题-synchronized博客


    解决安全问题,找到此程序 多线程执行共享数据/变化共享数据的代码,然后用synchronized{} 

    package android.java.thread10;
    
    /**
     * 两个储户,到同一个银行存钱,每个人存了3次,一次1000000.00元
     * 1.描述银行
     * 2.描述储户任务
     * 3.分析这个多线程是否存在安全隐患
     */
    
    /**
     * 1.描述银行
     */
    class Bank {
    
        /**
         * 3.分析这个多线程是否存在安全隐患 这里就是多线程执行的共享对象的共享数据
         */
        private double moneyAsset;
    
        public void addMoney(double moneyAsset) {
    
            /**
             * 多线程执行共享数据/变化共享数据的代码,然后用synchronized{}
             */
            synchronized (Bank.class) { // 只持有一把锁Bank.class
                this.moneyAsset += moneyAsset;
                System.out.println(Thread.currentThread().getName() + "存入" + this.moneyAsset + "元");
            }
        }
    
    }
    
    /**
     * 2.描述储户任务
     */
    class Customer implements Runnable {
    
        /**
         * 3.分析这个多线程是否存在安全隐患 这里就是多线程执行的共享对象
         */
        private Bank bank = new Bank();
    
        @Override
        public void run() {
            for (int i = 0; i < 3; i++) {
                bank.addMoney(1000000.00);
            }
        }
    }
    
    public class BankTest {
    
        public static void main(String[] args) {
            // 定义执行的任务
            Runnable customer = new Customer();
    
            // 线程执行>>>定义执行的任务
            new Thread(customer).start();
            new Thread(customer).start();
        }
    
    }

    执行结果:

     

  • 相关阅读:
    JavaScript内置对象String对象下常用的方法
    JavaScript内置对象String对象
    JavaScript内置对象Math产生一个16进制的随机颜色值
    JavaScript内置对象Math查询一组数中的最大值
    JavaScript内置对象Date常用方法总结
    JavaScript内置对象Date常用函数
    JavaScript内置对象Date----格式化时间
    C++学习笔记30:模板与型式参数化
    C++学习笔记29:运行期型式信息2
    C++学习笔记28:运行期型式信息
  • 原文地址:https://www.cnblogs.com/android-deli/p/10230449.html
Copyright © 2011-2022 走看看