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();
        }
    
    }

    执行结果:

     

  • 相关阅读:
    luogu 1865 数论 线性素数筛法
    洛谷 2921 记忆化搜索 tarjan 基环外向树
    洛谷 1052 dp 状态压缩
    洛谷 1156 dp
    洛谷 1063 dp 区间dp
    洛谷 2409 dp 月赛题目
    洛谷1199 简单博弈 贪心
    洛谷1417 烹调方案 dp 贪心
    洛谷1387 二维dp 不是特别简略的题解 智商题
    2016 10 28考试 dp 乱搞 树状数组
  • 原文地址:https://www.cnblogs.com/android-deli/p/10230449.html
Copyright © 2011-2022 走看看