线程不安全的两个例子
1. 购买车票:
package Thread; public class UnSafeBuyTicket { public static void main(String[] args) { BuyTicket buyTicket=new BuyTicket(); new Thread(buyTicket,"李四").start(); new Thread(buyTicket,"王五").start(); new Thread(buyTicket,"黄牛").start(); } } class BuyTicket implements Runnable{ private int ticketNums=10; boolean flag=true; @Override public void run() { while (flag) { try { buy(); } catch (InterruptedException e) { e.printStackTrace(); } } } public void buy() throws InterruptedException { if (ticketNums <= 0) { flag=false; return; } Thread.sleep(10); System.out.println(Thread.currentThread().getName()+"拿了"+ticketNums--); } }
2. 银行取钱
package Thread; public class UnSafeBank { public static void main(String[] args) { Acount acount = new Acount(100, "结婚基金"); Drawing you = new Drawing(acount, 50, "你"); Drawing girlFriend = new Drawing((acount), 100, "老婆"); you.start(); girlFriend.start(); } } //账户 class Acount{ int money;//余额 String name; //卡名 public Acount(int money, String name) { this.money=money; this.name=name; } } //银行,模拟取钱 class Drawing extends Thread{ Acount acount; //账户 int drawingMoney; //取的钱 int nowMoney; //现在手里有多少钱 public Drawing(Acount acount, int drawingMoney, String name) { super(name); this.acount=acount; this.drawingMoney=drawingMoney; } //取钱 @Override public void run(){ //判断有没有钱 if (acount.money - drawingMoney < 0) { System.out.println(Thread.currentThread().getName() + "余额不足"); return; } //sleep可以放大问题的发生性 try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } acount.money-=drawingMoney; nowMoney+=drawingMoney; System.out.println(acount.name + "余额为:" + acount.money); //Thread.currentThread().getName()=this.getName(); 等号两边都是取得当前线程名。this指当前类对象。 System.out.println(this.getName()+"手里的钱"+nowMoney); } }