欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java中ThreadLocal的應(yīng)用場(chǎng)景實(shí)例分析

 更新時(shí)間:2021年02月17日 10:16:06   作者:小妮淺淺  
在本篇文章里小編給大家整理的是一篇關(guān)于java中ThreadLocal的應(yīng)用場(chǎng)景實(shí)例分析,對(duì)此有興趣的朋友們可以學(xué)習(xí)參考下。

說到線程的安全,我們可以通過ThreadLocal來解決。但作為一種強(qiáng)大的變量,它的應(yīng)用場(chǎng)景遠(yuǎn)不止如此。在各類的框架中,我們依然可以使用來對(duì)它們進(jìn)行管理。同時(shí)在使用ThreadLocal時(shí)需要注意內(nèi)存泄漏的問題。下面我們就這兩點(diǎn)進(jìn)行分析,并帶來對(duì)應(yīng)代碼的展示。

1、各種框架中的應(yīng)用

Spring框架的事務(wù)管理中使用ThreadLocal來管理連接,每個(gè)線程是單獨(dú)的連接,當(dāng)事務(wù)失敗時(shí)不能影響到其他線程的事務(wù)過程或結(jié)果,還有大家耳聞目睹的ORM框架、Mybatis也是用ThreadLocal管理,SqlSession也是如此。

//Spring TransactionSynchronizationManager類
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
  DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
  Connection con = null;
  try {
    //此處省略N行代碼
    if (txObject.isNewConnectionHolder()) {
      //綁定數(shù)據(jù)庫(kù)連接到線程中
TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
    }
  }
  catch (Throwable ex) {
    if (txObject.isNewConnectionHolder()) {
      //當(dāng)發(fā)生異常時(shí),移除線程中的連接
      DataSourceUtils.releaseConnection(con, obtainDataSource());
      txObject.setConnectionHolder(null, false);
    }
    throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
  }
}

2、防止內(nèi)存泄漏

通常我們是使用如下的方式操作ThreadLocal,在使用完threadlocal后一定要remove掉,防止內(nèi)存泄露。

private static final ThreadLocal<LoginUser> loginUserLocal = new ThreadLocal<LoginUser>();
public static LoginUser getLoginUser() {
  return loginUserLocal.get();
}
public static void setLoginUser(LoginUser loginUser) {
  loginUserLocal.set(loginUser);
}
public static void clear() {
  loginUserLocal.remove();
}
//在使用完后一定要清理防止內(nèi)存泄露
try{
  loginUserLocal.set(loginUser);
  //執(zhí)行其他業(yè)務(wù)邏輯
}finally{
  loginUserLocal.remove();
}

java中ThreadLocal實(shí)例擴(kuò)展:

/**
 * 日期工具類(使用了ThreadLocal獲取SimpleDateFormat,其他方法可以直接拷貝common-lang)
 * @author Niu Li
 * @date 2016/11/19
 */
public class DateUtil {

 private static Map<String,ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<String, ThreadLocal<SimpleDateFormat>>();

 private static Logger logger = LoggerFactory.getLogger(DateUtil.class);

 public final static String MDHMSS = "MMddHHmmssSSS";
 public final static String YMDHMS = "yyyyMMddHHmmss";
 public final static String YMDHMS_ = "yyyy-MM-dd HH:mm:ss";
 public final static String YMD = "yyyyMMdd";
 public final static String YMD_ = "yyyy-MM-dd";
 public final static String HMS = "HHmmss";

 /**
  * 根據(jù)map中的key得到對(duì)應(yīng)線程的sdf實(shí)例
  * @param pattern map中的key
  * @return 該實(shí)例
  */
 private static SimpleDateFormat getSdf(final String pattern){
  ThreadLocal<SimpleDateFormat> sdfThread = sdfMap.get(pattern);
  if (sdfThread == null){
   //雙重檢驗(yàn),防止sdfMap被多次put進(jìn)去值,和雙重鎖單例原因是一樣的
   synchronized (DateUtil.class){
    sdfThread = sdfMap.get(pattern);
    if (sdfThread == null){
     logger.debug("put new sdf of pattern " + pattern + " to map");
     sdfThread = new ThreadLocal<SimpleDateFormat>(){
      @Override
      protected SimpleDateFormat initialValue() {
       logger.debug("thread: " + Thread.currentThread() + " init pattern: " + pattern);
       return new SimpleDateFormat(pattern);
      }
     };
     sdfMap.put(pattern,sdfThread);
    }
   }
  }
  return sdfThread.get();
 }

 /**
  * 按照指定pattern解析日期
  * @param date 要解析的date
  * @param pattern 指定格式
  * @return 解析后date實(shí)例
  */
 public static Date parseDate(String date,String pattern){
  if(date == null) {
   throw new IllegalArgumentException("The date must not be null");
  }
  try {
   return getSdf(pattern).parse(date);
  } catch (ParseException e) {
   e.printStackTrace();
   logger.error("解析的格式不支持:"+pattern);
  }
  return null;
 }
 /**
  * 按照指定pattern格式化日期
  * @param date 要格式化的date
  * @param pattern 指定格式
  * @return 解析后格式
  */
 public static String formatDate(Date date,String pattern){
  if (date == null){
   throw new IllegalArgumentException("The date must not be null");
  }else {
   return getSdf(pattern).format(date);
  }
 }
}

到此這篇關(guān)于java中ThreadLocal的應(yīng)用場(chǎng)景實(shí)例分析的文章就介紹到這了,更多相關(guān)java中ThreadLocal的應(yīng)用場(chǎng)景淺析內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot使用alibaba的druid數(shù)據(jù)庫(kù)連接池錯(cuò)誤的問題及解決

    springboot使用alibaba的druid數(shù)據(jù)庫(kù)連接池錯(cuò)誤的問題及解決

    這篇文章主要介紹了springboot使用alibaba的druid數(shù)據(jù)庫(kù)連接池錯(cuò)誤的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Java中PreparedStatement的用法解析

    Java中PreparedStatement的用法解析

    這篇文章主要介紹了Java中PreparedStatement的用法解析,在JDBC應(yīng)用中,PreparedStatement是一種比Statement更好的選擇,PreparedStatement可以通過使用參數(shù)化查詢來避免SQL注入攻擊,并且可以提高查詢性能,需要的朋友可以參考下
    2023-09-09
  • Spring多線程事務(wù)處理解決方案

    Spring多線程事務(wù)處理解決方案

    這篇文章主要介紹了Spring多線程事務(wù)處理,本文主要介紹了spring多線程事務(wù)的解決方案,心急的小伙伴可以跳過上面的理論介紹分析部分直接看最終解決方案,需要的朋友可以參考下
    2024-03-03
  • idea中使用Inputstream流導(dǎo)致中文亂碼解決方法

    idea中使用Inputstream流導(dǎo)致中文亂碼解決方法

    很多朋友遇到一個(gè)措手不及的問題當(dāng)idea中使用Inputstream流導(dǎo)致中文亂碼及Java FileInputStream讀中文亂碼問題,針對(duì)這兩個(gè)問題很多朋友不知道該如何解決,下面小編把解決方案分享給大家供大家參考
    2021-05-05
  • 解決MyBatis中為類配置別名,列名與屬性名不對(duì)應(yīng)的問題

    解決MyBatis中為類配置別名,列名與屬性名不對(duì)應(yīng)的問題

    這篇文章主要介紹了解決MyBatis中為類配置別名,列名與屬性名不對(duì)應(yīng)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • MyBatis中傳入?yún)?shù)parameterType類型詳解

    MyBatis中傳入?yún)?shù)parameterType類型詳解

    這篇文章主要給大家介紹了關(guān)于MyBatis中傳入?yún)?shù)parameterType類型的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2018-04-04
  • 解讀Spring框架中常用的設(shè)計(jì)模式

    解讀Spring框架中常用的設(shè)計(jì)模式

    這篇文章主要介紹了解讀Spring框架中常用的設(shè)計(jì)模式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 通過字節(jié)碼看java中this的隱式傳參詳解

    通過字節(jié)碼看java中this的隱式傳參詳解

    這篇文章主要給大家介紹了關(guān)于如何通過字節(jié)碼看java中this的隱式傳參的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • Java程序員必備的11大IntelliJ插件(附地址)

    Java程序員必備的11大IntelliJ插件(附地址)

    這篇文章主要介紹了Java程序員必備的11大IntelliJ插件(附地址),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Java訪問權(quán)限控制的重要性深入講解

    Java訪問權(quán)限控制的重要性深入講解

    這篇文章主要給大家介紹了關(guān)于Java訪問權(quán)限控制的重要性的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11

最新評(píng)論