多线程同步与安全

发布时间 2023-04-03 21:22:10作者: 越狱兔狲

三大不安全线程

//模拟不安全的买票
public class TestBuyTicket {
   public static void main(String[] args) {
       maiPiao maiPiao=new maiPiao();

       new Thread(maiPiao,"小明").start();
       new Thread(maiPiao,"小红").start();
       new Thread(maiPiao,"小兰").start();
  }
}

class maiPiao implements Runnable{

   private int piao=10;
  boolean flag=true;
   @Override
   public void run() {

       while (flag) {
           try {
               buy();
          } catch (InterruptedException e) {
               throw new RuntimeException(e);
          }
      }
  }
   private void buy() throws InterruptedException {
        if (piao<=0){
            flag=false;
            return;
        }
        Thread.sleep(100);
       System.out.println(Thread.currentThread().getName()+"拿到了"+piao--);
  }
}
//模拟不安全取钱
public class TestBank {
   public static void main(String[] args) {
       ZhangHu zhangHu=new ZhangHu("结婚基金",100);

       YingHang yingHang=new YingHang(zhangHu,"我",50);
       YingHang yingHang2=new YingHang(zhangHu,"你",100);
       yingHang.start();
       yingHang2.start();
  }
}
class ZhangHu{
   public String name;
   public int money;

   public ZhangHu(String name, int money) {
       this.name = name;
       this.money = money;
  }
}

class YingHang extends Thread{


   private ZhangHu zhangHu;
   private int money;

   public YingHang(ZhangHu zhangHu, String name, int money) {
       super(name);
       this.zhangHu = zhangHu;
       this.money = money;
  }

   @Override
   public void run() {
       if (zhangHu.money-money<0){
           System.out.println("对不起,您的钱不够");
           return;
      }
       try {
           Thread.sleep(3000);
      } catch (InterruptedException e) {
           throw new RuntimeException(e);
      }
       System.out.println(zhangHu.name+"余额为"+zhangHu.money);
       zhangHu.money=zhangHu.money-money;
       System.out.println(zhangHu.name+"还剩"+zhangHu.money);
  }

}
//模拟不安全集合
public class TestFeList {
   public static void main(String[] args) {
       List<String> list=new ArrayList<>();
       for (int i = 0; i < 1000; i++) {
           new Thread(()->list.add(Thread.currentThread().getName())).start();
      }
       System.out.println(list.size());
  }

}

synchronized

synchronized 默认锁的是this

锁的对象就是变化的量,监视 的对象需要增删改的对象

用synchroized优化完的代码:

//在需要修改量的方法里加入synchroized
private synchronized void buy() throws InterruptedException {
        if (piao<=0){
            flag=false;
            return;
        }
        Thread.sleep(100);
       System.out.println(Thread.currentThread().getName()+"拿到了"+piao--);
  }

public void run() {
   //在需要修改变化的量加入synchronized的代码块
       synchronized (zhangHu){
           if (zhangHu.money-money<0){
               System.out.println("对不起,您的钱不够");
               return;
          }
           try {
               Thread.sleep(3000);
          } catch (InterruptedException e) {
               throw new RuntimeException(e);
          }
           System.out.println(zhangHu.name+"余额为"+zhangHu.money);
           zhangHu.money=zhangHu.money-money;
           System.out.println(zhangHu.name+"还剩"+zhangHu.money);
      }

  }
public class TestFeList {
   public static void main(String[] args) {
       List<String> list=new ArrayList<>();
       for (int i = 0; i < 1000; i++) {
           synchronized (list){
               new Thread(()->list.add(Thread.currentThread().getName())).start();
          }

      }
       try {
           Thread.sleep(3000);
      } catch (InterruptedException e) {
           throw new RuntimeException(e);
      }
       System.out.println(list.size());
  }

}