//不安全的买票 //线程不安全,有负数或者多人买到同一张票 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 num = 10; private boolean flag = true;//判断是否停止线程 Thread的stop已经废弃不建议使用 @Override public void run() { //买票 while (flag){ buy(); } } public void buy(){ //判断是否有票 if(num<=0){ flag = false; return ; } try { //模拟延时(放大问题的发生性) Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } //买票 System.out.println(Thread.currentThread().getName()+"买到了第"+num--+"票"); } }
解决方法:通过关键字synchronized来设置同步锁 在buy()方法前面添加synchronized关键字来锁定这个方法
public synchronized void buy(){ //判断是否有票 if(num<=0){ flag = false; return ; } try { //模拟延时(放大问题的发生性) Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } //买票 System.out.println(Thread.currentThread().getName()+"买到了第"+num--+"票"); }如上图添加了synchronized关键字后就避免了多人抢到同一张票的情况,也避免了在没有票的情况下继续出票的情况 2.不安全的取钱
//不安全的取钱 //两个人去银行取钱,账户 public class UnsafeBank { public static void main(String[] args) { Account account = new Account(100, "结婚基金"); Drawing you = new Drawing(account, 50, "你"); Drawing grilFriend = new Drawing(account, 100, "grilFriend"); grilFriend.start(); you.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 drawingMoney;//取多少钱 int nowMoney;//现在手里有多少钱 public Drawing(Account account,int drawingMoney,String name){ super(name); this.account = account; this.drawingMoney = drawingMoney; } @Override public void run() { //判断账户里面有没有钱 if(account.money-drawingMoney<0){ System.out.println(Thread.currentThread().getName()+"钱不够了,取不了"); return; } //sleep 放大问题的发生性 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //卡内余额 = 余额 - 你取的钱 account.money = account.money - drawingMoney; //你手上的钱 nowMoney = nowMoney + drawingMoney; System.out.println(account.name +"余额为:"+account.money); //hread.currentThread().getName() = this.getName(); System.out.println(this.getName()+"手里的钱"+nowMoney); } }上述的问题就是你去50万,你老婆去100万,结果银行还倒贴了50万
解决方法:给银行账户添加锁 synchronized(account)
@Override public void run() { synchronized (account){ //判断账户里面有没有钱 if(account.money-drawingMoney<0){ System.out.println(Thread.currentThread().getName()+"钱不够了,取不了"); return; } //sleep 放大问题的发生性 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //卡内余额 = 余额 - 你取的钱 account.money = account.money - drawingMoney; //你手上的钱 nowMoney = nowMoney + drawingMoney; System.out.println(account.name +"余额为:"+account.money); //hread.currentThread().getName() = this.getName(); System.out.println(this.getName()+"手里的钱"+nowMoney); } }只要有一个人取完后另一个人就会因为余额不足取不了,保证了线程的安全
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)