案例一(买票):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
public class BuyTicket implements Runnable{
private int ticketNum = 10;
private boolean flag = true;
@Override public void run() { while (flag){ buy(); } }
private void buy() { if(ticketNum <= 0){ flag = false; return; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "拿到第" + ticketNum-- + "张票"); }
public static void main(String[] args) { BuyTicket buyTicket = new BuyTicket();
new Thread(buyTicket,"苦逼的我").start(); new Thread(buyTicket,"牛逼的你们").start(); new Thread(buyTicket,"可恶的黄牛党").start(); } }
|
发现结果有很多种情况如复数,0,-1。或者两个人买到了同一张票
发现问题:
多个线程操作同一个资源的情况下,线程不安全,数据混乱。(拿到两个一样得东西 或者 拿到不存在的数据)
两个人买到同一张票好理解,但是这个复数和-1是怎么来的呢?
比如3个人(A,B,C)买票,因为没有锁,没有同步,3个人看到的都是第1票A买完就剩下0张,—-》A买了第1张
因为在A买最后一张票的时候,B看到的是1,所以依旧能够进行资源抢夺,所以A买完后剩下0张—-》B买了第0张票
同理C也是看到的是1张票,所以进入资源抢夺,B买完后,剩下-1,—》C买了第-1张票
案例二(银行取钱):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
public class SafeBank { public static void main(String[] args) { Account account = new Account(100, "结婚基金");
Drawing you = new Drawing(account, 50, "你"); Drawing girlfriend = new Drawing(account, 100, "girlfriend");
you.start(); girlfriend.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; } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
account.money = account.money - drawingMoney;
nowmoney = nowmoney + drawingMoney;
System.out.println(account.name+"余额为:"+account.money);
System.out.println(this.getName()+"手里的钱为:"+account.money);
} }
|
案例三:(集合不安全)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package com.hbf.demo01;
import java.util.ArrayList; import java.util.List;
public class SafeList { public static void main(String[] args) { List<String> list = new ArrayList<>(); for (int i = 0; i < 10000; i++) {
new Thread(()->{ list.add(Thread.currentThread().getName()); }).start(); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(list.size()); } }
|
应该是10000个才对!!