java中synchronized修飾程式碼塊(兩種建立執行緒的方式講解賣票程式)
阿新 • • 發佈:2019-02-04
格式:
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(); } }