java多線程售票程序中synchronized用法反思

   通過對以下兩個例子,談談對synchronized的理解:

      代碼1:

public class Ticket implements Runnable {
 private static int  num=100;
 public static void main(String[] args) {
 
  Thread t1=new Thread(new Ticket(),"t1");
  Thread t2=new Thread(new Ticket(),"t2");
  Thread t3=new Thread(new Ticket(),"t3");
  Thread t4=new Thread(new Ticket(),"t4");
  Thread t5=new Thread(new Ticket(),"t5");
  t1.start();
  t2.start();
  t3.start();
  t4.start();
  t5.start();
 }
 synchronized void getTicket(String name){
  if(num>0){
   System.out.println(name+"-----"+num);
   num--;
  }
  try {
   Thread.sleep(500);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  }
 public void run() {
  while(num>0)
   this.getTicket(Thread.currentThread().getName());
 }
}

輸出結果爲什麼同一張票被賣出多次,而有的票沒賣出,例如:

 

 

代碼2:

public class Sell  implements Runnable{
     private int total;
     public  Sell(int total) {
  this.total=total;
 }
 @Override
 public void run() {
  // TODO Auto-generated method stub
  
  while (total>0) {
   System.out.println("tickets" +total+"is sell");
   synchronized  (new Integer(total)) {
    if (total>0) {
     total--;
       }
    try {
     Thread.sleep(2000);
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
  System.out.println("tickets  is selled");
    
   }
   
   
  }
  
  
                       }
  
 
 
 
 public static void main(String[] args) {
  int total=10;
  Sell sell=new Sell(total);
  Thread thread1=new Thread(sell);
  Thread thread2=new Thread(sell);
  Thread thread3=new Thread(sell);
  Thread thread4=new Thread(sell);
  thread1.start();
  thread2.start();
  thread3.start();
  thread4.start();
  
 }
 
}

    synchronized 鎖的是對象,例子一中,其實也相當於得到了Sell 對象的對象鎖,所以同步的只是對象對方法的調用,而售票時最重要的是對票的同步,爲了使tickets 同步,可以將票數封裝成對象,使synchronized 得到此對象的對象鎖,這樣就不會得到同一個票被賣多次的情況.

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章