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 @   gzs1024  阅读(472)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示