隨筆 - 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 閱讀(234) 評論(0)  編輯  收藏 所屬分類: J2se

          主站蜘蛛池模板: 莎车县| 巫溪县| 上林县| 浠水县| 沙洋县| 北安市| 台中市| 定远县| 龙口市| 雅江县| 哈密市| 桐庐县| 洪泽县| 高密市| 肇东市| 邮箱| 拜城县| 潮州市| 芦山县| 日照市| 山阴县| 正定县| 丹寨县| 霍山县| 龙里县| 四子王旗| 达尔| 开远市| 康平县| 盐边县| 新乐市| 光泽县| 鹤庆县| 沁源县| 舞钢市| 宝应县| 水城县| 宜君县| 安宁市| 保山市| 古蔺县|