java多執行緒併發庫高階應用 之 執行緒範圍內共享資料
轉自:http://blog.csdn.net/xushuaic/article/category/1335611
筆記摘要:
所謂執行緒範圍內共享資料,即對於相同的程式程式碼,多個模組在同一個執行緒中執行時要共享一份資料,而在另外執行緒中執行時又共享另外一份資料,
API中為我們提供了一個操作執行緒範圍內共享資料的類ThreadLocal,對於執行緒範圍內共享資料的應用,在ThreadLocal的應用場景中進行了介紹,然後
主要對它的使用進行講解,演示了由單一資料的共享到將多個數據封裝到一個物件中,然後進行共享。在開始先用一個Map集合簡單實現執行緒範圍內資料的共享
一、使用Map實現執行緒範圍內資料的共享
原理:
將執行緒物件作為map的鍵存入,這樣就保證了map物件的唯一,也就保證了執行緒內資料的唯一
關鍵:
明確一點,把當前執行緒物件作為map集合的鍵存進去
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Random;
- publicclass ThreadScopeShareData {
-
privatestaticint data = 0; //定義一個全域性的成員變數
- privatestatic Map<Thread, Integer> threadData = new HashMap<Thread, Integer>();
- publicstaticvoid main(String[] args) {
- //啟動兩個執行緒
- for(int i=0;i<2;i++){
- new Thread(new Runnable(){
- @Override
-
publicvoid run() {
- int data = new Random().nextInt(); //準備一個數據
- System.out.println(Thread.currentThread().getName()
- + " has put data :" + data);
- //把當前執行緒物件作為鍵,就可以保證map物件的唯一,即保證執行緒內的資料唯一
- threadData.put(Thread.currentThread(), data);
- new A().get();
- new B().get();
- }
- }).start();
- }
- }
- //定義一個類模擬獲取資料
- staticclass A{
- publicvoid get(){
- int data = threadData.get(Thread.currentThread());
- System.out.println("A from " + Thread.currentThread().getName()
- + " get data :" + data);
- }
- }
- staticclass B{
- publicvoid get(){
- int data = threadData.get(Thread.currentThread());
- System.out.println("B from " + Thread.currentThread().getName()
- + " get data :" + data);
- }
- }
- }
列印結果
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物件,只是重新賦值而已
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Random;
- publicclass ThreadLocalTest {
- privatestatic ThreadLocal<Integer> x = new ThreadLocal<Integer>();
- //建立一個儲存封裝類物件的ThreadLocal
- privatestatic ThreadLocal<MyThreadScopeData> myThreadScopeData = new ThreadLocal<MyThreadScopeData>();
- privatestaticint data = 0;
- publicstaticvoid main(String[] args){
- //產生兩個執行緒
- for(int i=0;i<2;i++){
- new Thread(new Runnable(){
- @Override
- publicvoid run() {
- //共享單一的資料
- int data = new Random().nextInt();
- System.out.println(Thread.currentThread().getName()+"has put data : "+data);
- x.set(data);
- //共享多個數據
- //將資料封裝在myData物件中,並將myData作為myThreadScopeData的鍵
- MyThreadScopeData myData = new MyThreadScopeData();
- myData.setName("name "+data);
- myData.setAge(data);
- myThreadScopeData.set(myData);
- new A().get();
- new B().get();
- }
- }).start();
- }
- }
- staticclass A{
- publicvoid get(){
- int data = x.get();
- System.out.println("A from "+Thread.currentThread().getName()+" get data :"+data);
- //從myData中取出資料,並獲取當前執行緒名,資料
- MyThreadScopeData myData = myThreadScopeData.get();
- System.out.println("A from "+Thread.currentThread().getName()+" getMyData: " +
- myData.getName() + "," +myData.getAge());
- }
- }
- staticclass B{
- publicvoid get(){
- int data = x.get();
-
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