synchronized 是鎖物件還是鎖程式碼
阿新 • • 發佈:2018-12-20
package java_thread.mysynchronized; //synchronized 鎖是所物件還是鎖程式碼 //原文:https://www.cnblogs.com/QQParadise/articles/5059824.html public class synchronized_test1 { //在Java中,synchronized關鍵字是用來控制執行緒同步的,就是在多執行緒的環境下,控制synchronized程式碼段不被多個執行緒同時執行。synchronized既可以加在一段程式碼上,也可以加在方法上。 //關鍵是,不要認為給方法或者程式碼段加上synchronized就萬事大吉 public static void main(String[] args) { /*for (int i = 0; i < 3; i++) { Thread thread = new MyThread(); thread.start(); } */ //執行結果: /*test開始.. test開始.. test開始.. test結束.. test結束.. test結束.. 啟動了三個執行緒,每隔執行緒雖然都有sycn關鍵字 但是鎖得住不是地段程式碼而是當前執行緒test 個個執行緒沒有相同物件的引用所以不會產生預期的效果 */ /* Sync sync=new Sync(); for(int i = 0; i < 3; i++) { //synchronized(Sync.class) { 這種寫法是錯誤的 因為這個鎖需要線上程內才能生效 同理若是這個鎖生效,那實現的情況就是多個執行緒呼叫main這個方法(自己理解,若是錯位,希望各位能夠指正。謝謝!) Thread thread = new Mythread2(sync); thread.start(); }*/ /* 執行結果: test開始.. test結束.. test開始.. test結束.. test開始.. test結束.. 其傳入的是相同的物件 而物件內有相應的物件鎖 所以不能併發操作 */ //synchronized鎖住的是程式碼還是物件。答案是:synchronized鎖住的是括號裡的物件,而不是程式碼。對於非static的synchronized方法,鎖的就是物件本身也就是this。 /* 那麼,如果真的想鎖住這段程式碼,要怎麼做?也就是,如果還是最開始的那段程式碼,每個執行緒new一個Sync物件,怎麼才能讓test方法不會被多執行緒執行。 解決也很簡單,只要鎖住同一個物件不就行了。例如,synchronized後的括號中鎖同一個固定物件,這樣就行了。這樣是沒問題,但是,比較多的做法是讓synchronized鎖這個類對應的Class物件。 * */ for (int i = 0; i < 3; i++) { Thread thread = new Mythread3(); thread.start(); } } } class MyThread extends Thread { public void run() { Sync sync = new Sync(); sync.test(); } } class Sync{ public void test() { System.out.println("test開始.."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("test結束.."); } } class Mythread2 extends Thread{ private Sync sycn2; public Mythread2(Sync sycn2) { this.sycn2=sycn2; } public void run() { synchronized(Sync.class) { sycn2.test(); } } } class Mythread3 extends Thread{ public void run() { Sync sycn2=new Sync(); synchronized(Sync.class) { sycn2.test(); } } }
//原文:https://www.cnblogs.com/QQParadise/articles/5059824.html
建議各位還是去看看原文章