java多线程安全问题出现的原因以及解决思路

## 出现原因
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 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,不会再出现负数

 

 

你可能感兴趣的:(java多线程安全问题出现的原因以及解决思路)