多个线程同时操作同一数据资源时,会不安全,出现数据紊乱
因为每个线程都有自己的内存区,当他们处理数据时,会将共享的数据复制一份加载到自己的内存区中,因此就会导致紊乱
举例1:小明、小红和老师同时去买票。现在总共有15张门票,如果没有门票了就不能再买了。
为了让并发问题更明显,我们在run方法中让当前线程睡觉20ms
public class TicketThread implements Runnable{
private int ticket = 15;
public static void main(String[] args) {
TicketThread ticketThread = new TicketThread();
//开启三个线程
new Thread(ticketThread,"小明").start();
new Thread(ticketThread,"小红").start();
new Thread(ticketThread,"老师").start();
}
@Override
public void run() {
while (true) {
if(ticket <= 0) break;
try {
//线程睡觉
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"--->拿到第"+(ticket--)+"张票");
}
}
}
顺序混乱:
出现0张和-1张票
举例2:爸爸妈妈同时去取钱,银行账户里面有100w,此时爸爸计划取50w,妈妈计划取100w,两个人同时去取钱。
public class UnsafeBank {
public static void main(String[] args) {
Account account = new Account(100);
new Bank("爸爸",account,50).start();
new Bank("妈妈",account,100).start();
}
}
//账户
class Account {
int money;
public Account(int money) {
this.money = money;
}
}
//银行
class Bank extends Thread{
Account account;
int drawingmoney;
public Bank(String Name, Account account, int drawingmoney) {
super(Name);
this.account = account;
this.drawingmoney = drawingmoney;
}
@Override
public void run() {
//没钱了
if(account.money < drawingmoney){
System.out.println("没钱了, "+Thread.currentThread().getName()+"不能取了");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//取钱
account.money -= drawingmoney;
System.out.println(Thread.currentThread().getName()+"取了" + drawingmoney);
System.out.println("余额"+account.money);
}
}
结果,余额是负数: