konhon

          忘掉過去,展望未來。找回自我,超越自我。
          逃避不一定躲的過, 面對不一定最難過, 孤單不一定不快樂, 得到不一定能長久, 失去不一定不再擁有, 可能因為某個理由而傷心難過, 但我卻能找個理由讓自己快樂.

          Google

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            203 Posts :: 0 Stories :: 61 Comments :: 0 Trackbacks

              1.方法聲明時使用,放在范圍操作符(public等)之后,返回類型聲明(void等)之前.這時,線程獲得的是成員鎖,即一次只能有一個線程進入該方法,其他線程要想在此時調用該方法,只能排隊等候,當前線程(就是在synchronized方法內部的線程)執行完該方法后,別的線程才能進入.
           
                例如:

                public synchronized void synMethod() {
                  
          //方法體
                }

              2.對某一代碼塊使用,synchronized后跟括號,括號里是變量,這樣,一次只有一個線程進入該代碼塊.此時,線程獲得的是成員鎖.例如:

                public int synMethod(int a1){
                  synchronized(a1) 
          {
                    
          //一次只能有一個線程進入
                  }

                }


              3.synchronized后面括號里是一對象,此時,線程獲得的是對象鎖.例如:

           

           public class MyThread implements Runnable {
              
          public static void main(String args[]) {
              MyThread mt 
          = new MyThread();
              Thread t1 
          = new Thread(mt, "t1");
              Thread t2 
          = new Thread(mt, "t2");
              Thread t3 
          = new Thread(mt, "t3");
              Thread t4 
          = new Thread(mt, "t4");
              Thread t5 
          = new Thread(mt, "t5");
              Thread t6 
          = new Thread(mt, "t6");
              t1.start();
              t2.start();
              t3.start();
              t4.start();
              t5.start();
              t6.start();
            }


            
          public void run() {
              synchronized (
          this{
                System.
          out.println(Thread.currentThread().getName());
              }

            }

          }
           
           

           
              對于3,如果線程進入,則得到當前對象鎖,那么別的線程在該類所有對象上的任何操作都不能進行.在對象級使用鎖通常是一種比較粗糙的方法。為什么要將整個對象都上鎖,而不允許其他線程短暫地使用對象中其他同步方法來訪問共享資源?如果一個對象擁有多個資源,就不需要只為了讓一個線程使用其中一部分資源,就將所有線程都鎖在外面。由于每個對象都有鎖,可以如下所示使用虛擬對象來上鎖:

           

           class FineGrainLock {

             MyMemberClass x, y;
             Object xlock 
          = new Object(), ylock = new Object();

             
          public void foo() {
                synchronized(xlock) 
          {
                   
          //access x here
                }


                
          //do something here - but don't use shared resources

                synchronized(ylock) 
          {
                   
          //access y here
                }

             }


             
          public void bar() {
                synchronized(
          this{
                   
          //access both x and y here
                }

                
          //do something here - but don't use shared resources
             }

            }



               4.synchronized后面括號里是類,此時,線程獲得的是對象鎖.例如:

           

          class ArrayWithLockOrder{
            
          private static long num_locks = 0;
            
          private long lock_order;
            
          private int[] arr;

            
          public ArrayWithLockOrder(int[] a)
            
          {
              arr 
          = a;
              synchronized(ArrayWithLockOrder.
          class{//-----這里
                num_locks++;             // 鎖數加 1。

                lock_order 
          = num_locks;  // 為此對象實例設置唯一的 lock_order。
              }

            }

            
          public long lockOrder()
            
          {
              
          return lock_order;
            }

            
          public int[] array()
            
          {
              
          return arr;
            }

            }


            
          class SomeClass implements Runnable
           
          {
            
          public int sumArrays(ArrayWithLockOrder a1,
                                 ArrayWithLockOrder a2)
            
          {
              
          int value = 0;
              ArrayWithLockOrder first 
          = a1;       // 保留數組引用的一個
              ArrayWithLockOrder last = a2;        // 本地副本。
              int size = a1.array().length;
              
          if (size == a2.array().length)
              
          {
                
          if (a1.lockOrder() > a2.lockOrder())  // 確定并設置對象的鎖定
                {                                     // 順序。
                  first = a2;
                  last 
          = a1;
                }

                synchronized(first) 
          {              // 按正確的順序鎖定對象。
                  synchronized(last) {
                    
          int[] arr1 = a1.array();
                    
          int[] arr2 = a2.array();
                    
          for (int i=0; i<size; i++)
                      value 
          += arr1[i] + arr2[i];
                  }

                }

              }

              
          return value;

            }

            
          public void run() {
              
          //
            }

            }


            
              對于4,如果線程進入,則線程在該類中所有操作不能進行,包括靜態變量和靜態方法,實際上,對于含有靜態方法和靜態變量的代碼塊的同步,我們通常用4來加鎖.

          posted on 2005-08-16 20:23 konhon 優華 閱讀(105126) 評論(32)  編輯  收藏 所屬分類: Java

          Feedback

          # re: synchronized的4種用法 2012-12-19 21:04 迷一樣
          很通俗易懂,學習了  回復  更多評論
            

          # re: synchronized的4種用法 2013-03-30 21:59 candy_code
          通篇都是在扯淡。
          synchronized鎖的永遠是對象,而不是代碼塊。synchronized作為方法修飾符時鎖的對象是調用者。不同的對象仍然訪問此方法不會構成同步。
          至于這句:
          public int synMethod(int a1){
          synchronized(a1) {
          //一次只能有一個線程進入
          }
          }
          更是扯淡中的扯淡。 這句話編譯器都不會讓你通過。樓主可以自己敲代碼試試。希望樓主不要再發表這種誤人子弟的言論。  回復  更多評論
            

          # re: synchronized的4種用法 2013-04-25 20:54 todo
          文中很多點是錯的,摟主快傷了吧  回復  更多評論
            

          # re: synchronized的4種用法 2013-07-13 23:19 圣戰風云
          @candy_code
          你說的沒錯!  回復  更多評論
            

          # re: synchronized的4種用法 2013-07-23 00:35 李唐靖
          誤人子弟。搞得我還以為我理解錯了。  回復  更多評論
            

          # re: synchronized的4種用法 2013-07-24 02:31 酷乞丐
          感覺通篇都講錯了。我之所以上網搜,是想知道
          synchronized(this) {
          //access y here
          }
          代表了什么,如果所是鎖對象,那應該是它自身,而它自身本來就只存在一根線程里啊。又何來鎖住其它線程的。除非是單例,例如struts1的Action。  回復  更多評論
            

          # re: synchronized的4種用法 2013-07-29 01:33 whxp
          同意,實踐證明@candy_code
            回復  更多評論
            

          # re: synchronized的4種用法[未登錄] 2013-09-23 01:45
          第二種方法用不上,報錯,其他還沒看  回復  更多評論
            

          # re: synchronized的4種用法 2014-04-02 22:15 gdlbbxzsc
          這個 按照我的理解的話,應該說分兩種吧?
          第一種是 對象鎖 無論是在 方法前面加 sync 還是 在 代碼塊括號內加,都一樣 鎖住的是 對象。
          方法 鎖得 是 當前類 對象(方法加static另說,相當于類鎖),一個類的兩個對象調用同一方法是不會阻塞的。
          代碼塊 所得 也是對象,如果是 this的話 跟 方法鎖是一樣的。
          如果是其他對象。如 string,那么 就是當這個類的創建的 所有對象 想調用這個 代碼塊的時候,都會阻塞,因為String 對象 被 某一個類對象 使用中么。。
          代碼塊還有一種 就是 類鎖,aaa。class 這種 當這個時候 就相當于 static sync
          所有 對象 都會 阻塞  回復  更多評論
            

          # re: synchronized的4種用法 2014-06-16 22:02 laj
          都是從哪復制到啊,誰是第一個寫這篇文章的人  回復  更多評論
            

          # re: synchronized的4種用法 2014-07-07 04:06 god
          沒有成員鎖,只有對象鎖和類對象鎖  回復  更多評論
            

          # re: synchronized的4種用法 2014-07-15 09:36 我心飛翔
          @candy_code
          是的,我也覺得,本來極簡的同步,在這里搞的這么復雜,我們經常用的無非就是2種,一種是鎖對象的,另一種是鎖代碼塊  回復  更多評論
            

          # re: synchronized的4種用法 2014-07-28 00:36
          日,誤人子弟啊  回復  更多評論
            

          # re: synchronized的4種用法[未登錄] 2014-07-29 07:49 deepblue
          講解synchronized內容的文章,我印象最深刻的是這篇文章,大家也可以去看看,與本文的角度不太一樣的:http://www.strutshome.com/index.php/archives/495  回復  更多評論
            

          # re: synchronized的4種用法 2014-08-03 22:42 的撒發生
          @deepblue
          他媽哪都有你  回復  更多評論
            

          # re: synchronized的4種用法[未登錄] 2015-01-07 11:34 bonus
          樓主得罪人了嗎?哪來這么多帶強烈感情色彩的噴子。即使有小瑕疵,但是對象鎖和塊鎖的道理還是對的。synchronized(this/obj)的區別搞懂了再來噴吧。感覺很詭異這樓!  回復  更多評論
            

          # re: synchronized的4種用法[未登錄] 2015-01-07 11:37 bonus
          @candy_code
          沒編譯錯誤,已經運行,敢問錯在哪里。意見不同也不能說人家扯淡.  回復  更多評論
            

          # re: synchronized的4種用法[未登錄] 2015-01-07 12:06 bonus
          最基本的問題,判斷是否需要同步,首先要看這塊資源是否有其它線程共同調用。那共同調用這塊如果是代碼塊,就是塊鎖(哪怕是System.out.println)也是鎖你沒商量,通常出現在多個線程是通過同一個線程類生成的,share代碼;如果共用的不是代碼塊而只是對象,那鎖的就是對象。究其根本就是看爭奪的資源是什么。不要孔乙己一樣研究回子的寫法死記硬背,強烈建議深入理解其機制。  回復  更多評論
            

          # re: synchronized的4種用法[未登錄] 2015-01-07 12:27 bonus
          再次重申,有對象鎖,也有塊鎖。塊鎖是絕對存在的!如果沒有塊的概念,下面兩段代碼就沒什么不同了。但結果是,第一段代碼的20循環是同步的,因為被塊保護。而第二段代碼的20循環很顯然會被別的線程打亂。

          第一段:
          synchronized(obj){
          for (int i = 0; i<20; i++) {
          Thread.sleep(100);
          System.out.println(Thread.currentThread.getName());
          }
          obj.method();
          }

          第二段:
          for (int i = 0; i<20; i++) {
          Thread.sleep(100);
          System.out.println(Thread.currentThread.getName());
          }
          synchronized(obj){
          obj.method();
          }  回復  更多評論
            

          # re: synchronized的4種用法 2015-02-15 02:33 sjj
          @candy_code
          你所說的問題更大,synchronized是有塊鎖的,且修飾方法時鎖的絕不是調用者,而是指調用該方法時必須排隊執行。不同的對象在調用該方法時都要排隊。

          樓主的代碼中,synchronized如果改為修飾對象就行了
          public int synMethod(Integer a1){
          synchronized(a1) {
          //一次只能有一個線程進入
          }
          }  回復  更多評論
            

          # re: synchronized的4種用法 2015-02-27 20:03 背黑鍋
          啥玩意啊!synchronized(this)這樣才是一次只有一個線程進入  回復  更多評論
            

          # re: synchronized的4種用法 2015-03-30 21:50 游客
          private void show(int threadNo) {
          synchronized(threadNo){
          for (int i = 0; i < 10; i++) {
          System.out.println("內d"+threadNo+i);
          }
          }

          }


          int is not a valid type's argument for the synchronized statement  回復  更多評論
            

          # re: synchronized的4種用法 2015-06-29 01:54 jileniao.net
          表示還沒能理解。  回復  更多評論
            

          # re: synchronized的4種用法[未登錄] 2015-07-23 21:33 aaa
          @candy_code
          我還以為是我理解錯誤了啊,誤人子弟  回復  更多評論
            

          # re: synchronized的4種用法 2015-12-18 03:40 mart
          我覺得也是 扯淡 呀  回復  更多評論
            

          # re: synchronized的4種用法 2016-01-25 02:33 個廣告
          建議直接刪掉帖子,  回復  更多評論
            

          # re: synchronized的4種用法 2016-01-29 07:04
          怪不得enjoy losing face!  回復  更多評論
            

          # re: synchronized的4種用法 2016-03-01 04:02 王小凱
          樓主SB,誤人子弟,別再編程了  回復  更多評論
            

          # re: synchronized的4種用法[未登錄] 2016-03-21 07:26 df
          樓主坑爹,趕緊回去買本書補習  回復  更多評論
            

          # re: synchronized的4種用法[未登錄] 2016-04-13 01:27 java
          誤人子弟的典范,垃圾中的戰斗機  回復  更多評論
            

          # re: synchronized的4種用法 2016-07-26 21:08 路人
          @java
          就算樓主錯了也不該這么說人家吧,這樣子,以后還有誰敢分享自己的見解了,說的對了沒有贊賞,說錯了被一大堆人噴。。。。  回復  更多評論
            

          # re: synchronized的4種用法 2016-08-10 04:13 a-little-love
          @路人
          就是就是!  回復  更多評論
            

          主站蜘蛛池模板: 镇宁| 连南| 大理市| 临安市| 洪洞县| 南召县| 小金县| 德江县| 增城市| 沛县| 浑源县| 澄迈县| 彩票| 广灵县| 锡林郭勒盟| 武清区| 安多县| 许昌市| 饶河县| 鹤庆县| 集贤县| 勐海县| 涞水县| 渝中区| 依安县| 社会| 新乡县| 红原县| 夏河县| 土默特左旗| 文昌市| 毕节市| 普宁市| 陆丰市| 巨野县| 通州市| 大埔区| 宁陕县| 台东县| 镇远县| 齐河县|