通過對以下兩個例子,談談對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 得到此對象的對象鎖,這樣就不會得到同一個票被賣多次的情況.