我們知道Thread存在單繼承侷限,並且數據不能共享,所以我們用Runnable來理解線程同步(當然用共享數據通過Thread也可以實現同步)。
拿下面例子說
class MyThread implements Runnable{
private int ticket = 5 ;
public void run(){
for(int i=0;i<100;i++){
if(ticket>0){
try{
Thread.sleep(300) ; // 加入延遲
}catch(InterruptedException e){
e.printStackTrace() ;
}
System.out.println("賣票:ticket = " + ticket-- );
}
}
}
};
public class SyncDemo01{
public static void main(String args[]){
MyThread mt = new MyThread() ; // 定義線程對象
Thread t1 = new Thread(mt) ;
Thread t2 = new Thread(mt) ;
Thread t3 = new Thread(mt) ;
t1.start() ;
t2.start() ;
t3.start() ;
}
};
運行結果
賣票:ticket = 5
賣票:ticket = 3
賣票:ticket = 4
賣票:ticket = 2
賣票:ticket = 1
賣票:ticket = 0
發現票數出現了0,因爲在run中加入了延遲,所以在--操作執行時或許另一個線程已經開始執行了,所以會出現票數不正常的情況。
所以我們要加入線程同步
synchronized(this){
if(ticket>0){
.........
}
}
這樣一個線程在執行時,其他線程會掛起,所以可以實現正常賣票。
當然同步還可以同步方法,同步數據,並不一定是同步代碼塊。
比如public synchronized void sale(){}