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