日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ThreadLocal 详解

發布時間:2025/3/8 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ThreadLocal 详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:https://www.cnblogs.com/renyuanwei/p/9635235.html

什么是ThreadLocal

?

? ??根據JDK文檔中的解釋:ThreadLocal的作用是提供線程內的局部變量,這種變量在多線程環境下訪問時能夠保證各個線程里變量的獨立性。

? ? 從這里可以看出,引入ThreadLocal的初衷是為了提供線程內的局部變量

?

ThreadLocal?不是一個線程,而是一個線程的本地化對象。當某個變量在使用?ThreadLocal?進行維護時,ThreadLocal?為使用該變量的每個線程分配了一個獨立的變量副本。

每個線程可以自行操作自己對應的變量副本,而不會影響其他線程的變量副本。

?

API 方法

ThreadLocal?的 API 提供了如下的 4 個方法。

1)protected T initialValue()

返回當前線程的局部變量副本的變量初始值。


2)T get()

返回當前線程的局部變量副本的變量值,如果此變量副本不存在,則通過?initialValue()?方法創建此副本并返回初始值。


3)void set(T value)

設置當前線程的局部變量副本的變量值為指定值。


4)void remove()

刪除當前線程的局部變量副本的變量值。


在實際使用中,我們一般都要重寫?initialValue()?方法,設置一個特定的初始值。

關于initialValue的初始化。本人嘗試了多種方式:

1 2 3 4 5 6 7 8 //new ThreadLocal方式:不推薦 ???????final?ThreadLocal<String> commandThreads =?new?ThreadLocal<String>() { ???????????@Override ???????????protected?String initialValue() { ???????????????return?"execute :"+System.currentTimeMillis(); ???????????} ???????}; ???????System.out.println(commandThreads.get());

  

1 2 3 4 5 //withInitial方式: ????????ThreadLocal<String> commandThreadnew = //???????????? ThreadLocal.withInitial(()-> "execute :"+System.currentTimeMillis()); ????????????????ThreadLocal.withInitial(()->new?String("execute :"+System.currentTimeMillis())); ????????System.out.println(commandThreadnew.get());

  

1 2 3 4 5 6 7 8 9 10 //(new Supplier<String>(){}方式 推薦 ???????ThreadLocal<String> commandThreadnew1 = ???????????????ThreadLocal.withInitial(new?Supplier<String>() { ???????????????????@Override ???????????????????public?String get() { ???????????????????????return??"execute :"+System.currentTimeMillis(); ???????????????????} ???????????????}); ???????System.out.println(? commandThreadnew1.get());

  

?

以下是關于ThreadLocal 解決多線程變量共享問題:

存在爭議點:

ThreadLocal到底能不能解決共享對象的多線程訪問問題?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 package?com.wuxianjiezh.demo.threadpool; public?class?MainTest { ????public?static?void?main(String[] args) { ????????Bank bank =?new?Bank(); ????????Thread xMThread =?new?Thread(() -> bank.deposit(200),?"小明"); ????????Thread xGThread =?new?Thread(() -> bank.deposit(200),?"小剛"); ????????Thread xHThread =?new?Thread(() -> bank.deposit(200),?"小紅"); ????????xMThread.start(); ????????xGThread.start(); ????????xHThread.start(); ????} } class?Bank { ????private?int?money =?1000; ????public?void?deposit(int?money) { ????????String threadName = Thread.currentThread().getName(); ????????System.out.println(threadName +?"--當前賬戶余額為:"?+?this.money); ????????this.money += money; ????????System.out.println(threadName +?"--存入 "?+ money +?" 后賬戶余額為:"?+?this.money); ????????try?{ ????????????Thread.sleep(1000); ????????}?catch?(InterruptedException e) { ????????????e.printStackTrace(); ????????} ????} }

  運行結果:存在多線程輸出結果混亂

1 2 3 4 5 6 小明--當前賬戶余額為:1000 小紅--當前賬戶余額為:1000 小紅--存入?200?后賬戶余額為:1400 小剛--當前賬戶余額為:1000 小剛--存入?200?后賬戶余額為:1600 小明--存入?200?后賬戶余額為:1200

  

使用?ThreadLocal?保存對象的局部變量。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public?class?MainTest { ????public?static?void?main(String[] args) { ????????Bank bank =?new?Bank(); ????????Thread xMThread =?new?Thread(() -> bank.deposit(200),?"小明"); ????????Thread xGThread =?new?Thread(() -> bank.deposit(200),?"小剛"); ????????Thread xHThread =?new?Thread(() -> bank.deposit(200),?"小紅"); ????????xMThread.start(); ????????xGThread.start(); ????????xHThread.start(); ????} } class?Bank { ????// 初始化賬戶余額為 100 ????ThreadLocal<Integer> account = ThreadLocal.withInitial(new?Supplier<Integer>() { ????????@Override ????????public?Integer get() { ????????????return?1000; ????????} ????}); ????public?void?deposit(int?money) { ????????String threadName = Thread.currentThread().getName(); ????????System.out.println(threadName +?"--當前賬戶余額為:"?+ account.get()); ????????account.set(account.get() + money); ????????System.out.println(threadName +?"--存入 "?+ money +?" 后賬戶余額為:"?+ account.get()); ????????try?{ ????????????Thread.sleep(1000); ????????}?catch?(InterruptedException e) { ????????????e.printStackTrace(); ????????} ????} }

  運行結果為:

1 2 3 4 5 6 7 小明--當前賬戶余額為:1000 小紅--當前賬戶余額為:1000 小紅--存入?200?后賬戶余額為:1200 小剛--當前賬戶余額為:1000 小剛--存入?200?后賬戶余額為:1200 小明--存入?200?后賬戶余額為:1200 可以看到,我們要的效果達到了。各線程間同時操作自己的變量,相互間沒有影響。

  

ThreadLocal 與 Thread 同步機制的比較

  • 同步機制采用了以時間換空間方式,通過對象鎖保證在同一個時間,對于同一個實例對象,只有一個線程訪問。

  • ThreadLocal?采用以空間換時間方式,為每一個線程都提供一份變量,各線程間同時訪問互不影響。

轉載于:https://www.cnblogs.com/sharpest/p/10884823.html

總結

以上是生活随笔為你收集整理的ThreadLocal 详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。