1. 程式人生 > >java中synchronized修飾程式碼塊(兩種建立執行緒的方式講解賣票程式)

java中synchronized修飾程式碼塊(兩種建立執行緒的方式講解賣票程式)

格式:

synchronized(類物件名 aa)

{

//同步程式碼塊

}

功能:

synchronized(類物件名 aa)的含義是:判斷aa是否已經被其他執行緒所霸佔,如果發現已經被其他執行緒霸佔,則當前執行緒陷入等待中,如果發現aa沒有被其他執行緒霸佔,則當前執行緒霸佔住aa物件,並執行同步程式碼塊,在當前執行緒執行同步程式碼塊時,其他執行緒將無法再執行同步程式碼塊(因為當前執行緒已經霸佔了aa物件),當前執行緒執行完同步程式碼塊後,會自動釋放對aa物件的霸佔,此時該執行緒會和其他執行緒相互競爭對aa的霸佔,最終CPU會選擇其中的某一個執行緒執行

最終導致的結果:一個執行緒正在操作某資源的時候,將不允許其他執行緒操作該資源,即一次只允許一個執行緒處理該資源。

synchronized修飾一個方法時,實際霸佔的是該方法的this指標所指向的物件,即實際霸佔的正在呼叫該方法的物件

注:霸佔的專業術語叫鎖定,霸佔住的的那個物件專業術語叫做監聽器

/*
	用建立執行緒的第二種方式 來買票
	本程式執行OK
*/

class A implements Runnable
{
	public int tickets = 100;
	String str = new String("哈哈");
	public void run()
	{
		while(true)
		{
			synchronized(str)
			{
				if(tickets > 0)
				{
					System.out.printf("%s執行緒正在賣出第%d張票\n", Thread.currentThread().getName(), tickets);
					--tickets;
					
				}
				else
					break;
			}
		}
	}
}

public class Rain {
	public static void main(String []args)
	{
		A aa = new A();
		Thread t1 = new Thread(aa);
		t1.start();
		Thread t2 = new Thread(aa);
		t2.start();
	}
}





/*
	用建立執行緒的第一種方式 來買票
	本程式執行OK
*/

class A extends Thread
{
	public static int tickets = 100;  //static不能省
	public static String str = new String("哈哈");  //static不能省
		
	public void run()
	{
		while (true)
		{
			synchronized (str)
			{
				if (tickets > 0)
				{
					System.out.printf("%s執行緒正在賣出第%d張票\n",
						Thread.currentThread().getName(), tickets);
					--tickets;	
				}
				else
				{
					break;
				}
			}
		}
	}
}

public class Rain
{
	public static void main(String[] args)
	{
		A aa1 = new A();
		aa1.start();	
			
		A aa2 = new A();
		aa2.start();		
	}
}