隨筆 - 3, 文章 - 152, 評論 - 17, 引用 - 0
          數據加載中……

          對Java同步一些理解

          對Java同步一些理解
          kingfish 2005
          ------------------------------------------------------------
          基本概念:
            每個Object都會有1個鎖.
            同步就是串行使用一些資源.

          (說明:以下有些例子為了突出重點,省略了不必要的代碼.特別是省掉了一些成員變量,就是需要同步的對象.)

          1. 多線程中對共享、可變的數據進行同步.
             對于函數中的局部變量沒必要進行同步.
             對于不可變數據,也沒必要進行同步.

             多線程中訪問共享可變數據才有必要.


          2. 單個線程中可以使用synchronized,而且可以嵌套,但無意義.
             class Test {
               public static void main(String[] args) {
                   Test t = new Test();
                   synchronized(t) {
                     synchronized(t) {
                        System.out.println("ok!");
                     }
                   }
               }
             }
            
          3. 對象實例的鎖
             class Test{
               public synchronized void f1(){
                   //do something here
               }

               public void f2(){
                  synchronized(this){
                     //do something here
                   }
               }
             }
           
             上面的f1()和f2()效果一致, synchronized取得的鎖都是Test某個實列(this)的鎖.
             比如: Test t = new Test();
                   線程A調用t.f2()時, 線程B無法進入t.f1(),直到t.f2()結束.

             作用: 多線程中訪問Test的同一個實例的同步方法時會進行同步.

          4. class的鎖
             class Test{
                 final static Object o= new Object();

                 public static synchronized void f1(){
                    //do something here
                 }
           
                 public static void f2(){
                   synchronized(Test.class){
                     //do something here
                   }
                 }
            
                public static void f3(){
                  try {
                    synchronized (Class.forName("Test")) {
                    //do something here
                    }
                  }
                  catch (ClassNotFoundException ex) {
                  }
                }
               
                 public static void g(){
                    synchronized(o){
                      //do something here
                    }
                 }
             }

             上面f1(),f2(),f3(),g()效果一致
             f1(),f2(),f3()中synchronized取得的鎖都是Test.class的鎖.
            
             g()是自己產生一個對象o,利用o的鎖做同步
             作用: 多線程中訪問此類或此類任一個實例的同步方法時都會同步. singleton模式lazily initializing屬于此類.

          5. static method
             class Test{
                private static int v = 0;

                public static void f1(){
                  //do something, 但函數中沒用用到v
                }

                public synchronized static void f2(){
                  //do something, 函數中對v進行了讀/寫.
                }  
             }

             多線程中使用Test的某個實列時,
              (1) f1()是線程安全的,不需要同步
              (2) f2()這個靜態方法中使用了函數外靜態變量,所以需要同步.

          6.  對線程的run()進行同步沒有意義,如 public synchronized void run()
              class Test extends Thread{
                public synchronized void run(){
                  while(true){
                     //do something
                  }
                }
               
                public synchronized void f(){
                   //...
                }
              }
              這種例子會有一個問題, 執行run()時(內部在循環), 外部無法執行f()


              class Test extends Thread{
                 public synchronized void run(){
                   //do something
                 }
              }
              這種例子同步基本沒用, 因為run()通常靠 new Test().start()來執行的.
              因為Test實例不同,鎖也不同.

          posted on 2005-02-27 17:37 閱讀(237) 評論(0)  編輯  收藏 所屬分類: J2se

          主站蜘蛛池模板: 颍上县| 金川县| 宝坻区| 巴塘县| 霍城县| 连平县| 松原市| 浙江省| 尖扎县| 平乡县| 龙南县| 自治县| 榕江县| 天台县| 淅川县| 柘荣县| 洪江市| 东莞市| 阳山县| 濮阳县| 敖汉旗| 浮山县| 蛟河市| 元江| 桃园市| 永德县| 枞阳县| 黄浦区| 安义县| 循化| 双峰县| 鞍山市| 平利县| 庆云县| 西藏| 彰武县| 扬州市| 林州市| 泌阳县| 合川市| 常德市|