qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          Java中線程安全問題個人理解

           線程安全問題是一個比較高深的問題,是很多程序員比較難掌握的一個技術難點,如果一個程序員對線程掌握的很好的話,那么這個程序員的內功修煉的是相當的好。

            在這里我主要說一下我對java中如何保證線程安全的一些個人見解,希望對各位有所幫助,那里有不對的地方敬請給位不吝賜教。

            線程安全問題主要出現在訪問臨界資源的時候,就是訪問同一個對象的時候,可能會出現無法挽回的損失,特別是在關于資金安全方面的時候,當然還有數據庫事務方面的問題。他們很類似,都是要保證數據的原子性。

            那么在java中如何保證線程安全呢?

            對與共同使用的對象進行加鎖,意思是我使用的時候,那么你就必須等待,等我用完之后你再用,反之依然。就像上廁所,你去的時候我是不能去的。

            如何加鎖呢?下面寫三個加鎖的方式

            首先看一下實例代碼

          1. public class TraditionalSynchornizedTest {  
          2.  /** 
          3.   * @param args 
          4.   */ 
          5.  public static void main(String[] args) {  
          6.   new TraditonalSynchornizedTest().sartThread();  
          7.  }  
          8.  public void sartThread(){  
          9.   final Outerput outerput = new Outerput();  
          10.   new Thread(new Runnable(){  
          11.    @Override 
          12.    public void run() {  
          13.     while(true){  
          14.      try {  
          15.       Thread.sleep(5);  
          16.      } catch (InterruptedException e) {  
          17.       e.printStackTrace();  
          18.      }  
          19.      outerput.print("zhangsanfeng");  
          20.     }  
          21.    }  
          22.      
          23.   }).start();  
          24.   new Thread(new Runnable(){  
          25.    @Override 
          26.    public void run() {  
          27.     while(true){  
          28.      try {  
          29.       Thread.sleep(5);  
          30.      } catch (InterruptedException e) {  
          31.       e.printStackTrace();  
          32.      }  
          33.      outerput.print("luxiaofeng");  
          34.     }  
          35.    }  
          36.      
          37.   }).start();  
          38.  }  
          39.  public class Outerput{  
          40.   public void print(String name){  
          41.    for(int i = 0;i < name.length(); i++){  
          42.     System.out.print(name.charAt(i));  
          43.    }  
          44.    System.out.println();  
          45.   }  
          46.  }  
          47. }

            以上代碼沒有對共同持有的對象outerput加鎖,所以會出現線程安全問題

          1、對代碼塊加鎖

            對共同持有的對象加鎖可以把內部類寫成這樣的

          1. public class Outerput{  
          2.   public void print(String name){  
          3.    synchronized (this) {  
          4.     for(int i = 0;i < name.length(); i++){  
          5.      System.out.print(name.charAt(i));  
          6.     }  
          7.     System.out.println();  
          8.    }  
          9.   }  
          10.  }

            2、對非靜態方法加鎖,加鎖的對象是this

          1. public class Outerput{  
          2.   public synchronized void print(String name){  
          3.    for(int i = 0;i < name.length(); i++){  
          4.     System.out.print(name.charAt(i));  
          5.    }  
          6.    System.out.println();  
          7.   }  
          8.  }

            3、對靜態方法加鎖的對象到底是誰?

          1. public static synchronized  void print2(String name){  
          2.    for(int i = 0;i < name.length(); i++){  
          3.     System.out.print(name.charAt(i));  
          4.    }  
          5.    System.out.println();  
          6.   }

            其實加鎖的對象是字節碼對象,Outerput.class

            如果和非靜態方法同時持有同一個對象時,可以持有同一個字節碼對象。



          posted on 2012-02-23 17:09 順其自然EVO 閱讀(155) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2012年2月>
          2930311234
          567891011
          12131415161718
          19202122232425
          26272829123
          45678910

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 吴堡县| 万荣县| 霍林郭勒市| 宿迁市| 玛曲县| 南城县| 电白县| 张家川| 太和县| 榆林市| 富蕴县| 宣武区| 抚松县| 七台河市| 东宁县| 体育| 通化市| 平安县| 德钦县| 商水县| 大丰市| 承德市| 雷山县| 泗水县| 红桥区| 凤庆县| 武义县| 平乡县| 渝中区| 乌审旗| 浦北县| 馆陶县| 会东县| 喀喇| 安义县| 郓城县| 冕宁县| 盐源县| 临洮县| 山丹县| 丰原市|