1. 程式人生 > >java多執行緒併發庫高階應用 之 執行緒範圍內共享資料

java多執行緒併發庫高階應用 之 執行緒範圍內共享資料

轉自:http://blog.csdn.net/xushuaic/article/category/1335611

筆記摘要:

 所謂執行緒範圍內共享資料,即對於相同的程式程式碼,多個模組在同一個執行緒中執行時要共享一份資料,而在另外執行緒中執行時又共享另外一份資料,

             API中為我們提供了一個操作執行緒範圍內共享資料的類ThreadLocal,對於執行緒範圍內共享資料的應用,在ThreadLocal的應用場景中進行了介紹,然後

             主要對它的使用進行講解,演示了由單一資料的共享到將多個數據封裝到一個物件中,然後進行共享。在開始先用一個Map集合簡單實現執行緒範圍內資料的共享

一、使用Map實現執行緒範圍內資料的共享

原理:

    將執行緒物件作為map的鍵存入,這樣就保證了map物件的唯一,也就保證了執行緒內資料的唯一

關鍵:  

    明確一點,把當前執行緒物件作為map集合的鍵存進去

  1. import java.util.HashMap;  
  2. import java.util.Map;  
  3. import java.util.Random;  
  4. publicclass ThreadScopeShareData {  
  5.     privatestaticint data = 0;    //定義一個全域性的成員變數
  6.     privatestatic Map<Thread, Integer> threadData = new HashMap<Thread, Integer>();  
  7.     publicstaticvoid main(String[] args) {  
  8.         //啟動兩個執行緒
  9.         for(int i=0;i<2;i++){  
  10.             new Thread(new Runnable(){  
  11.                 @Override
  12.                 publicvoid run() {  
  13.                     int data = new Random().nextInt();  //準備一個數據
  14.                     System.out.println(Thread.currentThread().getName()   
  15.                             + " has put data :" + data);  
  16.                     //把當前執行緒物件作為鍵,就可以保證map物件的唯一,即保證執行緒內的資料唯一
  17.                     threadData.put(Thread.currentThread(), data);  
  18.                     new A().get();  
  19.                     new B().get();  
  20.                 }  
  21.             }).start();  
  22.         }  
  23.     }  
  24.     //定義一個類模擬獲取資料
  25.     staticclass A{  
  26.         publicvoid get(){  
  27.             int data = threadData.get(Thread.currentThread());  
  28.             System.out.println("A from " + Thread.currentThread().getName()   
  29.                     + " get data :" + data);  
  30.         }  
  31.     }  
  32.     staticclass B{  
  33.         publicvoid get(){  
  34.             int data = threadData.get(Thread.currentThread());            
  35.             System.out.println("B from " + Thread.currentThread().getName()   
  36.                     + " get data :" + data);  
  37.         }         
  38.     }  
  39. }  

列印結果

Thread-0 has put data:-49248136

Thread-1 has put data:311124475

A from Thread-0 get data:-49248136

A from Thread-1 get data:311124475

B from Thread-0 get data:-49248136

B from Thread-1 get data:311124475


二、ThreadLocal類

1、ThreadLocal的作用和目的:

     用於實現執行緒內的資料共享,即對於相同的程式程式碼,多個模組在同一個執行緒中執行時要共享一份資料,而在另外執行緒中執行時又共享另外一份資料。

2、 每個執行緒呼叫全域性ThreadLocal物件的set方法,就相當於往其內部的map中增加一條記錄,key分別是各自的執行緒,value是各自的set方

      法傳進去的值。線上程結束時可以呼叫ThreadLocal.clear()方法,這樣會更快釋放記憶體,不呼叫也可以,因為執行緒結束後也可以自動釋放

      相關的ThreadLocal變數。

三、ThreadLocal的應用場景

1、訂單處理包含一系列操作:減少庫存量、增加一條流水臺賬、修改總賬,這幾個操作要在同一個事務中完成,通常也即同一個執行緒中進行處理,

      如果累加公司應收款的操作失敗了,則應該把前面的操作回滾,否則,提交所有操作,這要求這些操作使用相同的資料庫連線物件,而這些操作

      的程式碼分別位於不同的模組類中。

2、 銀行轉賬包含一系列操作:把轉出帳戶的餘額減少,把轉入帳戶的餘額增加,這兩個操作要在同一個事務中完成,它們必須使用相同的資料庫連

        接物件,轉入和轉出操作的程式碼分別是兩個不同的帳戶物件的方法。

3、例如Strut2的ActionContext,同一段程式碼被不同的執行緒呼叫執行時,該程式碼操作的資料是每個執行緒各自的狀態和資料,對於不同的執行緒來說,getContext方

       法拿到的物件都不相同,對同一個執行緒來說,不管呼叫getContext方法多少次和在哪個模組中getContext方法,拿到的都是同一個。

執行緒範圍內共享資料示意圖


四、實現對ThreadLocal變數的封裝, 讓外界不要直接操作ThreadLocal變數

      由於對基本型別的資料的封裝,這種應用相對很少見。而對物件型別的資料的封裝,比較常見,即讓某個類針對不同執行緒分別建立一個獨立的例項物件。      所以我們要對資料進行封裝。

實現方式一

示例說明:

       1、 該示例包含了對基本型別資料的共享和物件型別資料的共享

       2、定義一個全域性共享的ThreadLocal變數,然後啟動多個執行緒向該ThreadLocal變數中儲存一個隨機值,接著各個執行緒呼叫另外其他多個類

            的方法,這多個類的方法中讀取這個ThreadLocal變數的值,就可以看到多個類在同一個執行緒中共享同一份資料。

       3、但這裡每次儲存資料時,都是使用同一個ThreadLocal物件,只是重新賦值而已

  1. import java.util.HashMap;  
  2. import java.util.Map;  
  3. import java.util.Random;  
  4. publicclass ThreadLocalTest {  
  5.     privatestatic ThreadLocal<Integer> x = new ThreadLocal<Integer>();  
  6.     //建立一個儲存封裝類物件的ThreadLocal
  7.     privatestatic ThreadLocal<MyThreadScopeData> myThreadScopeData = new  ThreadLocal<MyThreadScopeData>();  
  8.     privatestaticint data = 0;  
  9.     publicstaticvoid main(String[] args){  
  10.         //產生兩個執行緒
  11.         for(int i=0;i<2;i++){  
  12.         new Thread(new Runnable(){  
  13.         @Override
  14.         publicvoid run() {  
  15.             //共享單一的資料
  16.             int data = new Random().nextInt();  
  17.             System.out.println(Thread.currentThread().getName()+"has put data : "+data);  
  18.             x.set(data);      
  19.             //共享多個數據
  20.             //將資料封裝在myData物件中,並將myData作為myThreadScopeData的鍵
  21.             MyThreadScopeData myData = new MyThreadScopeData();  
  22.             myData.setName("name "+data);  
  23.             myData.setAge(data);  
  24.             myThreadScopeData.set(myData);  
  25.             new A().get();  
  26.             new B().get();  
  27.             }  
  28.          }).start();  
  29.       }  
  30.    }  
  31.     staticclass A{  
  32.         publicvoid get(){  
  33.             int data = x.get();  
  34.             System.out.println("A from "+Thread.currentThread().getName()+" get data :"+data);  
  35.             //從myData中取出資料,並獲取當前執行緒名,資料
  36.             MyThreadScopeData myData = myThreadScopeData.get();  
  37.             System.out.println("A from "+Thread.currentThread().getName()+" getMyData: " +   
  38.                     myData.getName() + "," +myData.getAge());  
  39.         }  
  40.     }  
  41.     staticclass B{  
  42.         publicvoid get(){  
  43.             int data = x.get();  
  44.             System.out.println("B from "+Thread.currentThread().getName()+" get data :"

    相關推薦

    java執行併發高階應用 執行範圍共享資料

    轉自:http://blog.csdn.net/xushuaic/article/category/1335611 筆記摘要:  所謂執行緒範圍內共享資料,即對於相同的程式程式碼,多個模組在同一個執行緒中執行時要共享一份資料,而在另外執行緒中執行時又共

    執行併發高階應用 執行範圍共享資料

    筆記摘要:  所謂執行緒範圍內共享資料,即對於相同的程式程式碼,多個模組在同一個執行緒中執行時要共享一份資料,而在另外執行緒中執行時又共享另外一份資料,              API中為我們提供了一個操作執行緒範圍內共享資料的類ThreadLocal,對於執行緒範

    Java執行併發高階應用倒計時計數器CountDownLatch

    CountDownLatch類是一個倒計時計數器,在完成一組正在其他執行緒中執行的操作之前,它允許一個或多個執行緒一直等待。用給定的計數初始化 CountDownLatch。由於呼叫了countDown() 方法,所以在當前計數到達零之前,await 方法會一直受阻塞。之後,

    免費初級中級高階資料java視訊教程下載 加(微***信((號keepper,請備註java或掃下面2二3維4碼Java執行併發高階應用視訊教程下載

    更多免費初級中級高階大資料java視訊教程下載 加(微***信((號keepper,請備註java或掃下面2二3維4碼Java多執行緒與併發庫高階應用視訊教程下載java視訊教程01_傳智播客_張孝祥_傳統執行緒技術回顧.rarjava視訊教程02_傳智播客_張孝祥_傳統定時器技術回顧.rarjava視訊教程

    Java併發(五、六、七):執行範圍共享資料、ThreadLocal、共享資料的三種方法

    深切懷念傳智播客張孝祥老師,特將其代表作——Java併發庫視訊研讀兩遍,受益頗豐,記以後閱 05. 執行緒範圍內共享變數的概念與作用 執行緒範圍內共享資料圖解: 程式碼演示: class ThreadScopeShareData {        三個模組共享資料,主執

    執行範圍共享資料(一)

    Java開發過程中,若單個執行緒需要在多個物件與模組中訪問同一個變數,則通過靜態變數就可以實現,那麼問題來了,當存在多個執行緒,多個物件與模組去訪問同一變數時,就不行了。例如 public class

    Java執行執行併發條件阻塞Condition的應用

    鎖(Lock/synchronized)只能實現互斥不能實現通訊,Condition的功能類似於在傳統的執行緒技術中的,Object.wait()和Object.notify()的功能,在等待Condition時,允許發生"虛假喚醒",這通常作為對基礎平臺語義的讓步,對於大多

    Java執行併發】3.傳統執行互斥技術

    執行緒的同步互斥與通訊 互斥的問題在使用執行緒的時候是我們必須要注意的。 例如兩個執行緒同時開啟,由於業務規則,需要訪問同一個物件,要取得該物件 中的資料進行修改。 這樣多個執行緒對同一個資料進行操作的例項有很多,例如銀行交易。我們的賬戶中原來 有2000元,在同一時間,我

    Java高階應用執行池全面解析

      什麼是執行緒池?   很簡單,簡單看名字就知道是裝有執行緒的池子,我們可以把要執行的多執行緒交給執行緒池來處理,和連線池的概念一樣,通過維護一定數量的執行緒池來達到多個執行緒的複用。   執行緒池的好處 &n

    執行學習-----執行併發(八)

    AtomicInteger:實現多執行緒對共享Integer資料型別變數的同步。 AtomicIntegerArray: 實現對Integer陣列某個元素的同步。 AtomicIntegerFieldUpdater:實現對某個類裡的整數同步。 。。。。。。  java.

    網際網路架構執行併發程式設計高階教程(上)

    #基礎篇幅:執行緒基礎知識、併發安全性、JDK鎖相關知識、執行緒間的通訊機制、JDK提供的原子類、併發容器、執行緒池相關知識點  #高階篇幅:ReentrantLock原始碼分析、對比兩者原始碼,更加深入理解讀寫鎖,JAVA記憶體模型、先行發生原則、指令重排序 #環境說明:idea、ja

    java併發執行併發的使用

    1. 執行緒池的概念   在java5之後,就有了執行緒池的功能了,在介紹執行緒池之前,先來簡單看一下執行緒池的概念。假設我開了家諮詢公司,那麼每天會有很多人過來諮詢問題,如果我一個個接待的話,必

    java執行學習(八):執行高階使用執行池的使用(非常推薦,涉及:ThreadPoolExecutor,Executors,ThreadPoolExecutor,ScheduledThreadP)

    前言: 通過前面幾篇文章的學習,對多執行緒的知識瞭解了很多,同時也明白,其實學習不僅僅要看書,看文章,還要自己動手去敲demo,順便寫點文章收穫更多。當然多執行緒如果僅僅是用前面幾篇的知識的話,那未免也太膚淺了,畢竟,執行緒如果頻繁開啟和關閉的話,對系統資源的消耗那是相當大的。所以,

    『黑馬程式設計師』---java--深入加強--執行併發

    ----------- android培訓、java培訓、java學習型技術部落格、期待與您交流! ------------ 孝祥老師Java5執行緒併發庫講解---截圖示記筆記 java.util.concurrent.atomic  類 AtomicInteger

    執行併發(一)

    ThreadLocal 是執行緒區域性變數。在多執行緒中,實現每個執行緒中變數的私有性。 例子一 在該例子中,在同一個執行緒中通過呼叫類A和類B的getData()方法獲取的資料是一致的。 public class ThreadLocalTest {

    執行SCoop應用 時鐘(計時器)

    使用該庫的【時鐘(又叫:計時器)】功能,首先要做三件事: 第二:setup函式裡,呼叫mySCoop.start()命令 void setup() { mySCoop.start(); } 第三:loop函式裡,呼叫yield()命令 void

    執行SCoop應用 任務

    使用該庫的【任務】功能,首先要做三件事: 第二:setup函式裡,呼叫mySCoop.start()命令 void setup() { mySCoop.start(); } 第三:loop函式裡,呼叫yield()命令 void loop()

    java併發程式設計實戰》 執行安全性

    1.執行緒安全性 當多個執行緒訪問某個類時,不管執行時環境採用何種排程方式或者這些執行緒將如何交替執行,並且在主調程式碼中不需要任何額外的同步或協同,這個類都能表現出正確的行為,那麼這個類就是執行緒安全的。 無狀態物件一定是執行緒安全的,何為無狀態,就是類中不包含任何域,也不包含各種其

    Java併發包原始碼學習執行池(一)ThreadPoolExecutor原始碼分析

    Java中使用執行緒池技術一般都是使用Executors這個工廠類,它提供了非常簡單方法來建立各種型別的執行緒池: public static ExecutorService newFixedThreadPool(int nThreads) public static ExecutorService

    JAVA 併發程式設計-執行範圍共享變數(五)

    執行緒範圍內共享變數要實現的效果為:多個物件間共享同一執行緒內的變數未實現執行緒共享變數的demo:package cn.itcast.heima2; import java.util.HashMap; import java.util.Map; import java.u