最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java 中ThreadLocal本地線程和同步機(jī)制的比較

 更新時(shí)間:2017年03月22日 14:59:54   投稿:lqh  
這篇文章主要介紹了java 中ThreadLocal本地線程和同步機(jī)制的比較的相關(guān)資料,需要的朋友可以參考下

ThreadLocal的設(shè)計(jì)

首先看看ThreadLocal的接口:

Object get() ; // 返回當(dāng)前線程的線程局部變量副本 protected Object
initialValue(); // 返回該線程局部變量的當(dāng)前線程的初始值          
void set(Object value); // 設(shè)置當(dāng)前線程的線程局部變量副本的值

  ThreadLocal有3個(gè)方法,其中值得注意的是initialValue(),該方法是一個(gè)protected的方法,顯然是為了子類重寫而特意實(shí)現(xiàn)的。該方法返回當(dāng)前線程在該線程局部變量的初始值,這個(gè)方法是一個(gè)延遲調(diào)用方法,在一個(gè)線程第1次調(diào)用get()或者set(Object)時(shí)才執(zhí)行,并且僅執(zhí)行1次。ThreadLocal中的確實(shí)實(shí)現(xiàn)直接返回一個(gè)null:

protected Object initialValue() { return null; }

  ThreadLocal是如何做到為每一個(gè)線程維護(hù)變量的副本的呢?其實(shí)實(shí)現(xiàn)的思路很簡(jiǎn)單,在ThreadLocal類中有一個(gè)Map,用于存儲(chǔ)每一個(gè)線程的變量的副本。

比如下面的示例實(shí)現(xiàn):就相當(dāng)于存Map 這個(gè)是ThreadLocal的get方法的實(shí)現(xiàn)
 

public T get() {
    Thread t = Thread.currentThread();//獲取當(dāng)前線程
    ThreadLocalMap map = getMap(t);
    if (map != null) {
      ThreadLocalMap.Entry e = map.getEntry(this);
      if (e != null)
        return (T)e.value;
    }
    return setInitialValue();
  }
  
  
   ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
  }

ThreadLocal與其它同步機(jī)制的比較

  ThreadLocal和其它同步機(jī)制相比有什么優(yōu)勢(shì)呢?ThreadLocal和其它所有的同步機(jī)制都是為了解決多線程中的對(duì)同一變量的訪問(wèn)沖突,在普通的同步機(jī)制中,是通過(guò)對(duì)象加鎖來(lái)實(shí)現(xiàn)多個(gè)線程對(duì)同一變量的安全訪問(wèn)的。這時(shí)該變量是多個(gè)線程共享的,使用這種同步機(jī)制需要很細(xì)致地分析在什么時(shí)候?qū)ψ兞窟M(jìn)行讀寫,什么時(shí)候需要鎖定某個(gè)對(duì)象,什么時(shí)候釋放該對(duì)象的鎖等等很多。所有這些都是因?yàn)槎鄠€(gè)線程共享了資源造成的。ThreadLocal就從另一個(gè)角度來(lái)解決多線程的并發(fā)訪問(wèn),ThreadLocal會(huì)為每一個(gè)線程維護(hù)一個(gè)和該線程綁定的變量的副本,從而隔離了多個(gè)線程的數(shù)據(jù),每一個(gè)線程都擁有自己的變量副本,從而也就沒(méi)有必要對(duì)該變量進(jìn)行同步了。ThreadLocal提供了線程安全的共享對(duì)象,在編寫多線程代碼時(shí),可以把不安全的整個(gè)變量封裝進(jìn)ThreadLocal,或者把該對(duì)象的特定于線程的狀態(tài)封裝進(jìn)ThreadLocal。

  由于ThreadLocal中可以持有任何類型的對(duì)象,所以使用ThreadLocal get當(dāng)前線程的值是需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換。但隨著新的Java版本(1.5)將模版的引入,新的支持模版參數(shù)的ThreadLocal<T>類將從中受益。也可以減少?gòu)?qiáng)制類型轉(zhuǎn)換,并將一些錯(cuò)誤檢查提前到了編譯期,將一定程度地簡(jiǎn)化ThreadLocal的使用。

總結(jié)

    當(dāng)然ThreadLocal并不能替代同步機(jī)制,兩者面向的問(wèn)題領(lǐng)域不同。同步機(jī)制是為了同步多個(gè)線程對(duì)相同資源的并發(fā)訪問(wèn),是為了多個(gè)線程之間進(jìn)行通信的有效方式;而ThreadLocal是隔離多個(gè)線程的數(shù)據(jù)共享,從根本上就不在多個(gè)線程之間共享資源(變量),這樣當(dāng)然不需要對(duì)多個(gè)線程進(jìn)行同步了。所以,如果你需要進(jìn)行多個(gè)線程之間進(jìn)行通信, 則使用同步機(jī)制;如果需要隔離多個(gè)線程之間的共享沖突,可以使用ThreadLocal,這將極大地簡(jiǎn)化你的程序,使程序更加易讀、簡(jiǎn)潔。

ThreadLocal常見用途:

存放當(dāng)前session用戶
存放一些context變量,比如webwork的ActionContext
存放session,比如Spring hibernate orm的session

例子:用 ThreadLocal 實(shí)現(xiàn)每線程 Singleton

       線程局部變量常被用來(lái)描繪有狀態(tài)“單子”(Singleton) 或線程安全的共享對(duì)象,或者是通過(guò)把不安全的整個(gè)變量封裝進(jìn) ThreadLocal,或者是通過(guò)把對(duì)象的特定于線程的狀態(tài)封裝進(jìn) ThreadLocal。例如,在與數(shù)據(jù)庫(kù)有緊密聯(lián)系的應(yīng)用程序中,程序的很多方法可能都需要訪問(wèn)數(shù)據(jù)庫(kù)。在系統(tǒng)的每個(gè)方法中都包含一個(gè) Connection 作為參數(shù)是不方便的 — 用“單子”來(lái)訪問(wèn)連接可能是一個(gè)雖然更粗糙,但卻方便得多的技術(shù)。然而,多個(gè)線程不能安全地共享一個(gè) JDBC Connection。如清單 3 所示,通過(guò)使用“單子”中的 ThreadLocal,我們就能讓我們的程序中的任何類容易地獲取每線程 Connection 的一個(gè)引用。這樣,我們可以認(rèn)為 ThreadLocal 允許我們創(chuàng)建每線程單子。

package org.heinrich.app.connection;

import java.sql.Connection;

public class ConnectionUtils {
 
 
 private final static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
 
 
 public Connection getConnection(){
 Connection connection = threadLocal.get();
 if(connection ==null){
  connection = new DBHelper().getConn();
  threadLocal.set(connection);
 }
 
 return connection;
 }
 
 

}

package org.heinrich.app.connection;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
//數(shù)據(jù)庫(kù)連接
public class DBHelper {
 public static final String url = "jdbc:mysql://localhost:3306/fk_test";
 public static final String name = "com.mysql.jdbc.Driver";
 public static final String user = "root";
 public static final String password = "root";

 public Connection conn = null;

 public Connection getConn() {
 try {
  Class.forName(name);// 指定連接類型
  conn = DriverManager.getConnection(url, user, password);// 獲取連接
 } catch (Exception e) {
  e.printStackTrace();
 }
 return conn;
 }

}

簡(jiǎn)單的實(shí)現(xiàn)Mysql連接線程安全的一種方式

理論上來(lái)說(shuō),ThreadLocal是的確是相對(duì)于每個(gè)線程,每個(gè)線程會(huì)有自己的ThreadLocal。但是上面已經(jīng)講到,一般的應(yīng)用服務(wù)器都會(huì)維護(hù)一套線程池。因此,不同用戶訪問(wèn),可能會(huì)接受到同樣的線程。因此,在做基于TheadLocal時(shí),需要謹(jǐn)慎,避免出現(xiàn)ThreadLocal變量的緩存,導(dǎo)致其他線程訪問(wèn)到本線程變量。

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

  • 詳解基于IDEA2020.1的JAVA代碼提示插件開發(fā)例子

    詳解基于IDEA2020.1的JAVA代碼提示插件開發(fā)例子

    這篇文章主要介紹了詳解基于IDEA2020.1的JAVA代碼提示插件開發(fā)例子,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Java基礎(chǔ)之集合Set詳解

    Java基礎(chǔ)之集合Set詳解

    這篇文章主要介紹了Java基礎(chǔ)之集合Set詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • Java項(xiàng)目部署的完整流程(超詳細(xì)!)

    Java項(xiàng)目部署的完整流程(超詳細(xì)!)

    我相信很多Java新手都會(huì)遇到這樣一個(gè)問(wèn)題,跟著教材敲代碼,很容易,但是讓他完整的實(shí)現(xiàn)一個(gè)應(yīng)用項(xiàng)目卻不會(huì),下面這篇文章主要給大家介紹了關(guān)于Java項(xiàng)目部署的完整流程,需要的朋友可以參考下
    2022-07-07
  • Java深入探索單例模式的應(yīng)用

    Java深入探索單例模式的應(yīng)用

    單例模式(Singleton Pattern)是 Java 中最簡(jiǎn)單的設(shè)計(jì)模式之一。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式
    2022-06-06
  • 全面分析Java方法的使用與遞歸

    全面分析Java方法的使用與遞歸

    在java中,方法就是用來(lái)完成解決某件事情或?qū)崿F(xiàn)某個(gè)功能的辦法;程序調(diào)用自身的編程技巧稱為遞歸( recursion)。遞歸做為一種算法在程序設(shè)計(jì)語(yǔ)言中廣泛應(yīng)用。但是如果沒(méi)終止條件會(huì)造成死循環(huán),所以遞歸代碼里要有結(jié)束自調(diào)自的條件,本篇接下來(lái)講解一下方法與遞歸
    2022-04-04
  • SpringBoot實(shí)現(xiàn)網(wǎng)站的登陸注冊(cè)邏輯記錄

    SpringBoot實(shí)現(xiàn)網(wǎng)站的登陸注冊(cè)邏輯記錄

    登陸注冊(cè)功能是我們?nèi)粘i_發(fā)中經(jīng)常遇到的一個(gè)功能,下面這篇文章主要給大家介紹了關(guān)于SpringBoot實(shí)現(xiàn)網(wǎng)站的登陸注冊(cè)邏輯的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-10-10
  • java如何使用自己的maven本地倉(cāng)庫(kù)詳解

    java如何使用自己的maven本地倉(cāng)庫(kù)詳解

    這篇文章主要給大家介紹了關(guān)于java如何使用自己的maven本地倉(cāng)庫(kù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • JavaScript實(shí)現(xiàn)貪吃蛇游戲

    JavaScript實(shí)現(xiàn)貪吃蛇游戲

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Java設(shè)計(jì)模式之責(zé)任鏈模式

    Java設(shè)計(jì)模式之責(zé)任鏈模式

    這篇文章介紹了Java設(shè)計(jì)模式之責(zé)任鏈模式,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • 詳解在java中進(jìn)行日期時(shí)間比較的4種方法

    詳解在java中進(jìn)行日期時(shí)間比較的4種方法

    這篇文章主要介紹了詳解在java中進(jìn)行日期時(shí)間比較的4種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論

嘉定区| 柳江县| 阳信县| 凤城市| 闽侯县| 广平县| 儋州市| 正定县| 安溪县| 山东| 茶陵县| 称多县| 格尔木市| 乃东县| 庐江县| 南雄市| 浪卡子县| 盐亭县| 米林县| 南木林县| 平谷区| 亳州市| 云和县| 肥乡县| 克拉玛依市| 绩溪县| 四平市| 尼木县| 吕梁市| 南昌市| 兰州市| 乌恰县| 瑞金市| 略阳县| 眉山市| 屯留县| 府谷县| 丘北县| 中江县| 甘泉县| 山东省|