1. 程式人生 > >java多執行緒-同步函式的鎖

java多執行緒-同步函式的鎖

/* 
通過分析打印出錯誤票
多執行緒的執行出現了安全問題。 

問題的原因:
	當多條語句在操作同一個執行緒共享資料時,一個執行緒對多條語句執行了一部分,還沒有執行完
	另一個執行緒參與進來執行。導致共享資料的錯誤。
	
解決辦法:
	對多條操作共享資料的語句,只能讓一個執行緒都執行完。在執行過程中,其他執行緒不能參與執行。
	
java對多執行緒的安全的問題提供了專業的解決方式。

同步程式碼塊。
synchronized(物件)
{
     需要被同步的程式碼
}

同步函式。
public synchronized void fun(){
     需要被同步的程式碼塊
}

同步函式用的哪一個鎖
函式需要被物件呼叫,那麼函式都有一個所屬物件的引用,就是this。
所以同步函式使用的鎖是this

通過驗證
使用兩個執行緒來買票
一個執行緒在同步程式碼塊中
一個執行緒在同步函式中
都在執行買票動作。

如果同步函式被靜態修飾後,使用的鎖不是this
因為靜態方法中不可以定義this。
靜態進記憶體時,記憶體中沒有本類物件,但是一定有該類對應的位元組碼物件。

類名.class  該物件的型別是class。
使用的鎖是該類對應的位元組碼物件   類名.class
*/

class Ticket implements Runnable{
	private static int tick = 100;
	Object obj = new Object();
	boolean flag = true;
	public void run(){
		if(flag){   
		    while(true){
				synchronized(Ticket.class){
					if(tick>0){
						try{Thread.sleep(10);}catch(Exception e){}
						System.out.println(Thread.currentThread().getName()+"--synchronized : "+ tick--);
					}
			    }
			}
		}
		else{
			while(true)
				show();
		}
	}
	public static synchronized void show(){
		if(tick>0){
			try{Thread.sleep(10);}catch(Exception e){}
			System.out.println(Thread.currentThread().getName()+"--show-- : "+ tick--);
		}
	}
}
class TicketTest{
	public static void main(String[] args){
		
		Ticket t = new Ticket();
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		
		t1.start();
		try{Thread.sleep(10);}catch(Exception e){}
		t.flag = false;
		t2.start();
		
	}
}