<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 4,  comments - 9,  trackbacks - 0

     線程安全的本質體現在兩個方面,

     ?。磷兞堪踩憾嗑€程同時運行一段代碼

     ?。戮€程同步:一個線程還沒執行完,另一個線程又進來接著執行。

     看個簡單的例子。

    Java代碼
    1. public class ThreadSafe implements java.lang.Runnable {  
    2.       
    3.     int num = 1;  
    4.     public void run() {  
    5.         for (int i = 0; i < 3; i++) {  
    6.             num = num + 1;  
    7.             try {  
    8.                 Thread.sleep(2000);  
    9.             } catch (InterruptedException e) {  
    10.                 e.printStackTrace();  
    11.             }  
    12.             System.out.println("num is value +==="+Thread.currentThread().getName()+"---------" + num);  
    13.         }  
    14.     }  
    15.   
    16. }  
     
    TestMan.java 寫道
    package com.java.thread.test;

    public class TestMan {
    public static void main(String[] args) {
    Runnable safe=new ThreadSafe();
    Thread thread1=new Thread(safe,"thread1");
    Thread thread2=new Thread(safe,"thread2");
    thread1.start();
    thread2.start();
    }

    }

     運行結果

    num is value +===thread2---------3
    num is value +===thread1---------4
    num is value +===thread2---------5
    num is value +===thread1---------6
    num is value +===thread1---------7
    num is value +===thread2---------7

    很明顯是錯誤的,應為兩個線程共享同一個變量。這里就是變量的安全問題。

    解決辦法:

    1拋棄單實例,多線程的方式,用多實例,多線程的方式,這樣就和單線程是一個樣了,不會出錯,但是是最接近傳統的編程模式

    2不要用類的實例變量,經可能把變量封裝到方法內部。

    1類的解決辦法的代碼。

    Java代碼
    1. public class TestMan {  
    2.     public static void main(String[] args) {  
    3.         Runnable safe=new ThreadSafe();  
    4.         Runnable safe2=new ThreadSafe();  
    5.         Thread thread1=new Thread(safe,"thread1");  
    6.         Thread thread2=new Thread(safe2,"thread2");  
    7.         thread1.start();  
    8.         thread2.start();  
    9.     }  
    10.   
    11. }  
     

    運行結果

    num is value +===thread1---------2
    num is value +===thread2---------2
    num is value +===thread1---------3
    num is value +===thread2---------3
    num is value +===thread1---------4
    num is value +===thread2---------4
    2類解決辦法的代碼

    Java代碼
    1. public class ThreadSafe implements java.lang.Runnable {  
    2.       
    3.     public void run() {  
    4.         int num = 1;  
    5.         for (int i = 0; i < 3; i++) {  
    6.             num = num + 1;  
    7.             try {  
    8.                 Thread.sleep(2000);  
    9.             } catch (InterruptedException e) {  
    10.                 e.printStackTrace();  
    11.             }  
    12.             System.out.println("num is value +==="+Thread.currentThread().getName()+"---------" + num);  
    13.         }  
    14.     }  
    15.   
    16. }  
     
    Java代碼
    1. public class TestMan {  
    2.     public static void main(String[] args) {  
    3.         Runnable safe=new ThreadSafe();  
    4.   
    5.         Thread thread1=new Thread(safe,"thread1");  
    6.         Thread thread2=new Thread(safe,"thread2");  
    7.         thread1.start();  
    8.         thread2.start();  
    9.     }  
    10.   
    11. }  

     運行結果

    num is value +===thread2---------2
    num is value +===thread1---------2
    num is value +===thread1---------3
    num is value +===thread2---------3
    num is value +===thread1---------4
    num is value +===thread2---------4

     

    這兩種辦法,比較推薦適用第二個辦法,就是把變量經可能的封裝到風發內部,這樣他們就是線程的私有變量了。另外,從jdk1.2后,推出了 threadlocal 對象,它作為線程的一個局部變量,可以為每個線程創建一個副本,用來保存每個線程的屬性,各是各的,互不干擾。單每個 threadlocal變量只能保存一個變量,假如有多個變量要保存,那么就要寫多個threadlocal對象。

     

    我們把代碼改寫一下。

    Java代碼
    1. public class ThreadSafe implements java.lang.Runnable {  
    2.     ThreadLocal<Integer> local=new ThreadLocal<Integer>();  
    3.     public void run() {  
    4.         for (int i = 0; i < 3; i++) {  
    5.             if(local.get()==null){  
    6.                 local.set(new Integer(1));  
    7.             }  
    8.             int num=local.get().intValue();  
    9.             num=num+1;  
    10.             local.set(new Integer(num));  
    11.             try {  
    12.                 Thread.sleep(2000);  
    13.             } catch (InterruptedException e) {  
    14.                 e.printStackTrace();  
    15.             }  
    16.             System.out.println("num is value +==="+Thread.currentThread().getName()+"---------" + local.get().intValue());  
    17.         }  
    18.     }  
    19.   
    20. }  
     
    Java代碼
    1. public class TestMan {  
    2.     public static void main(String[] args) {  
    3.         Runnable safe=new ThreadSafe();  
    4.         Thread thread1=new Thread(safe,"thread1");  
    5.         Thread thread2=new Thread(safe,"thread2");  
    6.         thread1.start();  
    7.         thread2.start();  
    8.     }  
    9.   
    10. }  

     運行結果

    num is value +===thread2---------2
    num is value +===thread1---------2
    num is value +===thread1---------3
    num is value +===thread2---------3
    num is value +===thread1---------4
    num is value +===thread2---------4

    結果是一樣的,所以這里變量安全有3個辦法可以解決。

     

    然后在說說線程的同步的問題。我們看上面的運行結果。

    num is value +===thread2---------2
    num is value +===thread1---------2
    num is value +===thread1---------3
    num is value +===thread2---------3
    num is value +===thread1---------4
    num is value +===thread2---------4

    就 可以看出他們不是線程同步的,是thread1和thread2在交替執行的。在有些情況下,要求一段代碼在運行的過程中是一個不可分割的實 體,就是原子的。就是說當已經有線程在執行這段代碼的時候,其他的線程必須等待他執行完畢后才能竟來執行,這就是所謂的線程同步。

     

    java通過同步鎖來執行線程的同步和等待,也就是說,要不間斷執行的代碼需要放在synchronized關鍵字標識的代碼塊中??梢杂脕硇揎棿? 碼塊,也可以修飾方法。

     

    Java代碼
    1. public class ThreadSafe implements java.lang.Runnable{  
    2.     public synchronized void run() {  
    3.         int num = 1;  
    4.         for (int i = 0; i < 3; i++) {  
    5.             num = num + 1;  
    6.             try {  
    7.                 Thread.sleep(2000);  
    8.             } catch (InterruptedException e) {  
    9.                 e.printStackTrace();  
    10.             }  
    11.             System.out.println("num is value +==="+Thread.currentThread().getName()+"---------" + num);  
    12.         }  
    13.     }  
    14.   
    15.   
    16. }  
     
    Java代碼
    1. public class TestMan {  
    2.     public static void main(String[] args) {  
    3.         Runnable safe=new ThreadSafe();  
    4.         Thread thread1=new Thread(safe,"thread1");  
    5.         Thread thread2=new Thread(safe,"thread2");  
    6.         thread1.start();  
    7.         thread2.start();  
    8.     }  
    9.   
    10. }  

     運行結果

    um is value +===thread1---------2
    num is value +===thread1---------3
    num is value +===thread1---------4
    num is value +===thread2---------2
    num is value +===thread2---------3
    num is value +===thread2---------4

     

    可以看到thread1運行結束后thread2才開始運行的。代碼還可以這么寫

    Java代碼
    1. public class ThreadSafe implements java.lang.Runnable {  
    2.     public void run() {  
    3.         int num = 1;  
    4.         synchronized (this) {  
    5.             for (int i = 0; i < 3; i++) {  
    6.                 num = num + 1;  
    7.                 try {  
    8.                     Thread.sleep(2000);  
    9.                 } catch (InterruptedException e) {  
    10.                     e.printStackTrace();  
    11.                 }  
    12.                 System.out.println("num is value +==="  
    13.                         + Thread.currentThread().getName() + "---------" + num);  
    14.             }  
    15.         }  
    16.     }  
    17.   
    18. }  
     

    在啟用同步鎖機制以后,需要避免

    1無線等待,,線程B等待線程A執行完畢,然后線程A確進入了死循環。

    2循環等待:兩個線程相互調用,都要求要同步執行,這個時候就先會循環等待,我等你執行,你也在等我執行,這個時候就死鎖了
    posted on 2010-06-05 17:23 凌宇 閱讀(3609) 評論(0)  編輯  收藏

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


    網站導航:
     
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(3)

    隨筆檔案(3)

    文章檔案(14)

    相冊

    收藏夾

    Java

    最新隨筆

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 成人午夜影视全部免费看| 18禁止看的免费污网站| 亚洲人成在线观看| 最新欧洲大片免费在线 | 亚洲精品无码中文久久字幕| 亚洲国产精品激情在线观看 | 16女性下面扒开无遮挡免费| 国产精品久久久久久亚洲影视 | 亚洲欧洲校园自拍都市| 国产成人免费网站在线观看| 国产一精品一av一免费爽爽| 亚洲人成人无码.www石榴 | 亚洲色最新高清av网站| 亚洲午夜国产精品无码老牛影视| 亚洲日本在线免费观看| 乱人伦中文视频在线观看免费| 亚洲另类小说图片| 亚洲日韩一页精品发布| 最近中文字幕mv免费高清视频7| 精品亚洲永久免费精品| 色天使亚洲综合一区二区| 亚洲精品高清国产麻豆专区| ZZIJZZIJ亚洲日本少妇JIZJIZ| 欧美好看的免费电影在线观看| 99久久精品毛片免费播放| MM1313亚洲国产精品| 亚洲日韩乱码久久久久久| 亚洲桃色AV无码| 亚洲精品成人片在线观看| 日本免费一区二区三区最新| 国产成人yy免费视频| 国产一区二区三区免费| 国产精品福利片免费看| 亚洲精华国产精华精华液好用| 亚洲视频在线观看视频| 亚洲精品乱码久久久久久| 亚洲精品色婷婷在线影院| 日本成人免费在线| 啦啦啦在线免费视频| 色妞WWW精品免费视频| 精品久久8x国产免费观看|