java中ThreadLocal的應用場景實例分析
說到線程的安全,我們可以通過ThreadLocal來解決。但作為一種強大的變量,它的應用場景遠不止如此。在各類的框架中,我們依然可以使用來對它們進行管理。同時在使用ThreadLocal時需要注意內(nèi)存泄漏的問題。下面我們就這兩點進行分析,并帶來對應代碼的展示。
1、各種框架中的應用
Spring框架的事務管理中使用ThreadLocal來管理連接,每個線程是單獨的連接,當事務失敗時不能影響到其他線程的事務過程或結果,還有大家耳聞目睹的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ù)庫連接到線程中
TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
}
}
catch (Throwable ex) {
if (txObject.isNewConnectionHolder()) {
//當發(fā)生異常時,移除線程中的連接
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è)務邏輯
}finally{
loginUserLocal.remove();
}
java中ThreadLocal實例擴展:
/**
* 日期工具類(使用了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得到對應線程的sdf實例
* @param pattern map中的key
* @return 該實例
*/
private static SimpleDateFormat getSdf(final String pattern){
ThreadLocal<SimpleDateFormat> sdfThread = sdfMap.get(pattern);
if (sdfThread == null){
//雙重檢驗,防止sdfMap被多次put進去值,和雙重鎖單例原因是一樣的
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實例
*/
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);
}
}
}
到此這篇關于java中ThreadLocal的應用場景實例分析的文章就介紹到這了,更多相關java中ThreadLocal的應用場景淺析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
如何應對spring框架的HTTP ERROR 400 Bad Request錯
這篇文章主要介紹了如何應對spring框架的HTTP ERROR 400 Bad Request錯誤返回問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
關于json解析多層嵌套并轉(zhuǎn)為對應類(List)
在進行JSON解析時,遇到多層嵌套結構可通過遞歸或?qū)S脦靵韺崿F(xiàn),重要的是將嵌套的JSON對象準確轉(zhuǎn)化為對應的Java類,通常需要依賴如Gson或Jackson等庫,將JSONObject轉(zhuǎn)為JavaBean時,關注字段匹配與數(shù)據(jù)類型轉(zhuǎn)換2024-10-10
Spring?Boot實現(xiàn)JWT?token自動續(xù)期的實現(xiàn)
本文主要介紹了Spring?Boot實現(xiàn)JWT?token自動續(xù)期,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12

