## 出现原因
1)某一个操作不是原子性的操作
2)同一时间有多个线程同时执行这个操作
这时就可能会出现多线程安全的问题
如以下代码
//有库存,只是举例
public Inventory{
private long num=100;
public void descountInventory(int dcount){
if(this.num>0){
//如果你电脑比较快可能没问题还是正确的结果,这时你可用加大线程的数量,或者时在判断完大于0后sleep100毫秒。
// try{Thread.sleep(100); }catch(Exception e){}
this.num-=dcount;
System.out.print(this.num);
}else{
throw new Exception("库存不足");
}
}
}
//下面有一个库存扣减的工作
public class ProductRunnable implements Runnable{
private Inventory inventory;
public SellProductRunnable(Inventory inventory){
this.inventory =inventory
}
public void run(){
while(true){
try{
this.inventory.descountInventory(1);
}catch(Exception e){
break;
}
}
}
//启动多线程执行扣减库存操作
public class SellTest{
public static void main(String[] agr){
Inventory inventory=new Inventory();
for(int i=0;i<100<i++){
new Thread(ProductRunnable(inventory) ) .start();
}
}
}
执行SellTest,你会发现有时库存出现负数,主要是因为descountInventory操作不是原子性操作,这个操作中2步1)判断库存大于0 2)再减去一 当多个线程拿到num=1是一的时候,都同时去执行扣减操作,所以就出现负数
## 解决思路
把扣减库存的操作看着是一个原子操作,同一时间只能有一个线程执行,其实也很简单就是加一把线程安全锁,只需要修改Inventory就可以了。
public Inventory{
private long num=100;
public void descountInventory(int dcount){
synchronized(num){
if(this.num>0){ //如果你电脑比较快可能没问题还是正确的结果,这时你可用加大线程的数量,或者时在判断完大于0后sleep100毫秒。
// try{Thread.sleep(100); }catch(Exception e){}
this.num-=dcount; System.out.print(this.num);
}else{
throw new Exception("库存不足");
}
}
} }
再执行SellTest,不会再出现负数