Java基础学习:多线程19(三大不安全案例)

Java基础学习:多线程19

  • 三大不安全案例:

    • 买火车票;

    • 取钱;

    • List集合;

     

  • 代码案例1:买火车票

    ​
    /**
    * 不安全的买票:多个线程操作同一资源对象;
    * 1,线程不安全,有负数;(每个线程在自己的工作内存交互,内存控制不当会造成数据不一致)
    *
    */
    public class UnSafeBuyTicket {
    ​
       public static void main(String[] args) {
    ​
           //声明一个买票对象
           BuyTicket b=new BuyTicket();
    ​
    ​
           //三个人买票
           new Thread(b,"小明").start();
           new Thread(b,"老师").start();
           new Thread(b,"黄牛党").start();
    ​
      }
    ​
    }
    ​
    //买票
    class BuyTicket implements Runnable{
    ​
       //票
       private int ticketNums=10;
    ​
       boolean flag=true;//外部停止方式
    ​
    ​
       @Override
       public void run() {
           //买票
           while (flag){
               buy();
          }
    ​
      }
    ​
       private void buy(){
           //判断是否有票
           if(ticketNums<=0){
               flag=false;
               return;
          }
           try {
               Thread.sleep(100);//放大问题的发生性
          } catch (InterruptedException e) {
               e.printStackTrace();
          }
           //买票
           System.out.println(Thread.currentThread().getName()+"买到票了"+ticketNums-- );
    ​
      }
    }
  • 代码案例:取钱

    package com.ljx3.syn;
    ​
    /**
    * 不安全的去钱:不设计多个线程操作同一个对象;
    *
    * 2个人去银行取前,账户
    */
    public class UnSafeBank {
    ​
       public static void main(String[] args) {
    ​
           Account account=new Account(100,"上学");
           Drawing you=new Drawing(account,50,"你");
           Drawing girl=new Drawing(account,100,"girl");
    ​
           you.start();
           girl.start();
    ​
      }
    ​
    }
    ​
    ​
    //账户
    class Account{
    ​
       int money;//余额
       String name ;//户名
    ​
       public Account(int money, String name) {
           this.money = money;
           this.name = name;
      }
    }
    ​
    //银行:模拟取款
    class Drawing extends Thread{
    ​
       Account account;//账户
       int drawMoney;//取了多少钱
       int nowMoney;//现在手里有多少钱
    ​
       public Drawing(Account account,int drawMoney,String name){
           super(name);
           this.account=account;
           this.drawMoney=drawMoney;
    ​
      }
    ​
       //取钱
       @Override
       public void run() {
           //判断有没有钱
           if(account.money-drawMoney<0){
               System.out.println(Thread.currentThread().getName()+"钱不够,取不了");
               return ;
          }
           try {
               Thread.sleep(200);//放大问题的发生性
          } catch (InterruptedException e) {
               e.printStackTrace();
          }
    ​
           //卡内余额=余额-取的钱
           account.money=account.money-drawMoney;
           //手里的钱
           nowMoney=nowMoney+drawMoney;
    ​
           System.out.println("account.money余额为:"+account.money);
           //Thread.currentThread().getName() = this.getName()
           System.out.println(this.getName()+"手里的钱:"+nowMoney);
      }
    }
    ​

     

  • 代码案例3:List集合是不安全的

    ​
    /**
    * 线程不安全的集合:List
    *
    */
    public class UnSafeList {
       public static void main(String[] args) {
    ​
           List<String> list=new ArrayList<String>();
    ​
           for (int i = 0; i < 10000; i++) {
               new Thread(()->{
                   list.add(Thread.currentThread().getName());
              }).start();
          }
           try {
               Thread.sleep(3000);
          } catch (InterruptedException e) {
               e.printStackTrace();
          }
           System.out.println(list.size());//9997
    ​
      }
    }
    ​
    ​

     

  • 笔记:

    • 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致;

 

posted @ 2022-03-12 19:06  gzs1024  阅读(499)  评论(0)    收藏  举报