線程管理(九)使用本地線程變量

聲明:本文是《?Java 7 Concurrency Cookbook?》的第一章, 作者: Javier Fernández González 譯者:鄭玉婷 校對:方騰飛

使用本地線程變量

并發應用的一個關鍵地方就是共享數據。這個對那些擴展Thread類或者實現Runnable接口的對象特別重要。

如果你創建一個類對象,實現Runnable接口,然后多個Thread對象使用同樣的Runnable對象,全部的線程都共享同樣的屬性。這意味著,如果你在一個線程里改變一個屬性,全部的線程都會受到這個改變的影響。

有時,你希望程序里的各個線程的屬性不會被共享。 Java 并發 API提供了一個很清楚的機制叫本地線程變量。

在這個指南中, 我們將開發一個程序,這個程序用來描述在第一段話里的問題,和另一個程序使用本地線程變量機制解決這個問題。

準備

指南中的例子是使用Eclipse IDE 來實現的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打開并創建一個新的java項目。

怎么做呢

按照這些步驟來實現下面的例子:

1.? ?首先,我們來實現一個程序含有上述的問題。

創建一個類名為 UnsafeTask 并實現 Runnable 接口。 聲明一個?private?java.util.Date 屬性.

1 public?class?UnsafeTask?implements?Runnable{
2 private?Date startDate;

2. 實現UnsafeTask 對象的run() 方法,此方法會初始 startDate 屬性, 把值寫入控制臺,隨機休眠一段時間,最后在寫入startDate 屬性。

01@Override
02 public?void?run() {
03 startDate=new?Date();
04 System.out.printf("Starting Thread: %s : %s\n",Thread. currentThread().getId(),startDate);
05 try?{
06 TimeUnit.SECONDS.sleep( (int)Math.rint(Math.random()*10));
07 }?catch?(InterruptedException e) {
08e.printStackTrace();
09}
10 System.out.printf("Thread Finished: %s : %s\n",Thread. currentThread().getId(),startDate);
11}

3.? ?現在,來實現這個有問題例子的主類。創建一個 Main ?類和 main() 方法. 此方法會創建一個 UnsafeTask 類的對象,并開始3個線程使用這個對象,每個線程間休眠2秒。

01 public?class?Core {
02 public?static?void?main(String[] args) {
03 UnsafeTask task=new?UnsafeTask();
04 ?for?(int?i=0; i<10; i++){
05 Thread thread=new?Thread(task);
06thread.start();
07 try?{ TimeUnit.SECONDS.sleep(2);
08 }?catch?(InterruptedException e) {
09e.printStackTrace();
10}
11}
12}
13}

4.? ?在以下的裁圖,你可以發現這個程序的執行結果。每個線程有著不同的開始時間,但是全部都有相同的結束時間。

5.? ?如在之前提到的, 我們會使用本地線程變量機制來解決這個問題。

6.? ?創建一個類名為 SafeTask a一定實現 Runnable 接口。

1 public?class?SafeTask?implements?Runnable {

7.?? 聲明 ThreadLocal<Date> 類對象。此對象有隱含實現了 initialValue()方法. 此方法會返回真實日期。

1 private?static?ThreadLocal<Date> startDate=?new?ThreadLocal<Date>() {
2 protected?Date initialValue(){
3 return?new?Date();
4}
5};

8.? ?實現run()方法。它和 UnsafeClass的run() 方法功能一樣,只是改變了屬性的訪問方式。

01@Override
02 public?void?run() {
03 ??System.out.printf("Starting Thread: %s : %s\n",Thread.currentThread().getId(),startDate.get());
04 try?{
05 ??TimeUnit.SECONDS.sleep((int)Math.rint(Math.random()*10));
06 }?catch?(InterruptedException e) {
07e.printStackTrace();
08}
09 System.out.printf("Thread Finished: %s : %s\n",Thread.currentThread().getId(),startDate.get());
10}

9. ???這個例子的主類跟不安全例子一樣,把名字改成 Runnable 類。

10. 運行例子并分析不同處。

它是怎么工作的

在下面的截圖里,你可以看到線程安全模式下程序運行的結果。現在3個 Thread 對象都有他們自己的startDate 屬性值。看下圖:

本地線程變量為每個使用這些變量的線程儲存屬性值。可以用 get() 方法讀取值和使用 set() 方法改變值。 如果第一次你訪問本地線程變量的值,如果沒有值給當前的線程對象,那么本地線程變量會調用 initialValue() 方法來設置值給線程并返回初始值。

更多

本地線程類還提供 remove() 方法,刪除存儲在線程本地變量里的值。

Java 并發 API 包括 InheritableThreadLocal 類提供線程創建線程的值的遺傳性 。如果線程A有一個本地線程變量,然后它創建了另一個線程B,那么線程B將有與A相同的本地線程變量值。 你可以覆蓋 childValue() 方法來初始子線程的本地線程變量的值。 它接收父線程的本地線程變量作為參數。

原創文章,轉載請注明:?轉載自并發編程網 – ifeve.com本文鏈接地址:?線程管理(九)使用本地線程變量

文章轉自?并發編程網-ifeve.com

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282132.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282132.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282132.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

5訓練需要更改參數嗎_糖尿病病人需要多喝水嗎?多喝水的5大好處,了解一下...

糖尿病是典型的慢性疾病&#xff0c;需要在生活中多加講究&#xff0c;從各方面進行預防&#xff0c;其中喝水也是非常重要的一項調控方法。這就與糖尿病影響到患者的代謝功能有一定的關系&#xff0c;如果能夠保持良好的飲水習慣&#xff0c;就可以有效解決糖尿病帶來的影響。…

wordpress搭建博客 主題推薦 2019

一、generatepress2.14 主頁&#xff1a; 詳情頁&#xff1a; 二、 Astra 主頁&#xff1a; 詳情頁&#xff1a; 三、Bstone 主頁&#xff1a; 詳情頁&#xff1a; 四、Hestia 主頁&#xff1a; 詳情頁&#xff1a; 五、Rife free 主頁&#xff1a; 詳情頁&#xff1a;

Blazor學習之旅(1)初步了解Blazor

【Blazor】| 總結/Edison Zhou九月以來在學習Blazor做全棧開發&#xff0c;因此根據老習慣&#xff0c;我會將我的學習過程記錄下來&#xff0c;一來體系化整理&#xff0c;二來作為筆記供將來翻看。作為第一篇&#xff0c;我們先來了解一下這個Blazor到底是個什么鬼。什么是Bl…

英國如何推動分享經濟的發展?

——基于英國“分享經濟全球中心”戰略的深度分析 蔡雄山 騰訊研究院法律研究中心首席研究員 徐 俊 騰訊研究院助理研究員 “分享經濟具有巨大的經濟潛力&#xff0c;我希望確保英國處于分享經濟的前沿與中心&#xff0c;并且成為能夠與舊金山相媲美的高科技初創企業的發源地…

C#合并文件夾圖片列表 自定義排版順序

本次程序編寫主要為了將pdf word等文檔轉換為圖片后設置不同的打印排版 前提 目標文件夾中的圖片高寬都是一致的 /// <summary>/// 合并圖片/// </summary>/// <param name"savedictory">文件保存目錄</param>/// <param name"singl…

硬盤基本知識(一)

總體來說&#xff0c;硬盤結構包括&#xff1a;盤片、磁頭、盤片主軸、控制電機、磁頭控制器、數據轉換器、接口、緩存等幾個部份。所有的盤片&#xff08;一般硬盤里有多個盤片&#xff0c;盤片之間平行&#xff09;都固定在一個主軸上。在每個盤片的存儲面上都有一個磁頭&…

MySQL - 存儲過程

一、概述 存儲過程可以理解為一段 SQL 語句的集合&#xff08;相當于 PHP 中的一個函數方法&#xff0c;去實現業務邏輯&#xff09;&#xff0c;它們被事先編譯好并且存儲在數據庫中。 調用存儲過程與直接執行 SQL 語句的效果是相同的&#xff0c;但是存儲過程的一個好處是處理…

白話聊應用架構

產業互聯網時代&#xff0c;數字化轉型&#xff08;數字化演化歷史&#xff09;已成為一種趨勢&#xff0c;各行各業都投入到數字化轉型的浪潮中來。節后有個客戶項目參與者問我架構方面的事情&#xff0c;我想來想去對于非IT人來說&#xff0c;可能應用架構是最容易理解&#…

python大數_python處理大數字的方法

本文實例講述了python處理大數字的方法。分享給大家供大家參考。具體實現方法如下&#xff1a;def getFactorial(n):"""returns the factorial of n"""if n 0:return 1else:k n * getFactorial(n-1)return kfor k in range(1, 70):print "…

數據庫分庫分表、讀寫分離的原理和實現,以及使用場景

2019獨角獸企業重金招聘Python工程師標準>>> 為什么要分庫分表和讀寫分離&#xff1f; 類似淘寶網這樣的網站&#xff0c;海量數據的存儲和訪問成為了系統設計的瓶頸問題&#xff0c;日益增長的業務數據&#xff0c;無疑對數據庫造成了相當大的負載&#xff0c;同時…

談談一些有趣的CSS題目(十六)-- 奇妙的 background-clip: text

開本系列&#xff0c;談談一些有趣的 CSS 題目&#xff0c;題目類型天馬行空&#xff0c;想到什么說什么&#xff0c;不僅為了拓寬一下解決問題的思路&#xff0c;更涉及一些容易忽視的 CSS 細節。 解題不考慮兼容性&#xff0c;題目天馬行空&#xff0c;想到什么說什么&#x…

第五周軟件工程作業-每周例行報告

一、PSP T名稱C內容ST開始時間ED結束時間中斷時間/min實際時間/minScrum會議第一次Scrum會議10月13日11:3010月13日12:10040第二次Scrum會議10月14日15:3010月14日15:55025第三次Scrum會議10月15日13:3010月15日14:05035第四次Scrum會議10月16日11:3010月16日13:00090第五次Scr…

MySQL - 觸發器

一、概述 Mysql 允許通過觸發器、存儲過程、函數的形式來存儲代碼。 觸發器可以讓你在執行 Insert、Update、Delete的時候&#xff0c;執行一些特定的操作。可以在Mysql中指定是在Sql語句執行之前觸發還是執行后觸發。 二、使用觸發器需要注意的點 對每一個表的每一個事件&a…

Docker Desktop 可以直接啟用Kubernetes 1.25 了

作為目前事實上的容器編排系統標準&#xff0c;K8s 無疑是現代云原生應用的基石&#xff0c;很多同學入門可能直接就被卡到第一關&#xff0c;從哪去弄個 K8s 的環境&#xff0c; Docker Desktop 自帶了Kubernetes 服務&#xff0c;但是在過往的經驗中就是用梯子也安裝不了&…

截取url的host_java正則表達式獲取url的host示例

java正則表達式獲取url的host示例 復制代碼 代碼如下: public static String getHost(String url){if(url==null||url.trim().equals("")){return ""; } String host = ""; Pattern p = Pattern.compile("(?<=//|)((\\w)+\\.)+\\w+&qu…

MySQL - 視圖

一、概述 Mysql 5.0 版本后開始引入視圖。視圖本身是一個虛擬表&#xff0c;不存放任何數據。在使用 sql 語句訪問視圖的時候&#xff0c;他返回的數據都是在查詢過程中從其他表動態生成的。 二、使用視圖   1、創建視圖 CREATE VIEW comic_view as SELECT comic_id,name,pe…

Linux環境下壓縮與解壓命令大全

tar命令 解包&#xff1a;tar zxvf FileName.tar 打包&#xff1a;tar czvf FileName.tar DirName gz命令 解壓1&#xff1a;gunzip FileName.gz 解壓2&#xff1a;gzip -d FileName.gz 壓縮&#xff1a;gzip FileName .tar.gz 和 .tgz 解壓&#xff1a;tar zxvf FileName.tar.…

Centos 磁盤管理及配額管理

實驗內容&#xff1a;一.添加兩塊硬盤&#xff0c;使用LVM做成VG01組&#xff0c;在該VG中新建兩個LV。二.將這兩個LV格式化為ext4/xfs&#xff0c;開機自動掛載到系統mnt1,mnt2目錄下。三.lv02開啟磁盤配額功能&#xff0c;用來進行用戶與組分配額的實驗。四.在系統里添加用戶…

OnionArch - 采用DDD+CQRS+.Net 7.0實現的洋蔥架構

博主最近失業在家&#xff0c;找工作之余&#xff0c;看了一些關于洋蔥&#xff08;整潔&#xff09;架構的資料和項目&#xff0c;有感而發&#xff0c;自己動手寫了個洋蔥架構解決方案&#xff0c;起名叫OnionArch。基于最新的.Net 7.0 RC1, 數據庫采用PostgreSQL, 目前實現了…

spark寫出分布式的訓練算法_利用 Spark 和 scikit-learn 將你的模型訓練加快 100 倍...

在 Ibotta&#xff0c;我們訓練了許多機器學習模型。這些模型為我們的推薦系統、搜索引擎、定價優化引擎、數據質量等提供動力。它們在與我們的移動應用程序交互時為數百萬用戶做出預測。當我們使用 Spark 進行數據處理時&#xff0c;我們首選的機器學習框架是 scikit-learn。隨…