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

来源:互联网 发布:eia数据 编辑:程序博客网 时间:2024/06/06 04:34

   通过对以下两个例子,谈谈对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 得到此对象的对象锁,这样就不会得到同一个票被卖多次的情况.

 

 

 

 

原创粉丝点击