摘要:盡量少使用全局變量變量不是常量線程封閉比較好的封閉方法維護(hù)的是一個(gè)這個(gè)是線程的名稱多為我們所有封閉的值作為。在線程執(zhí)行完之后將中的數(shù)據(jù)清空防止內(nèi)存溢出。最后我們用測試發(fā)現(xiàn)打印了線程,中變量值只要是一個(gè)線程中不管在哪個(gè)類中都是共享的。
我們可以通過把對象設(shè)計(jì)成不可變對象來躲避并發(fā),我們還可以通過使用線程封閉來實(shí)現(xiàn)線程安全,所謂線程封閉
就是將數(shù)據(jù)都封裝到一個(gè)線程里,不讓其他線程訪問。
Ad-hoc 線程封閉程序控制實(shí)現(xiàn),比較脆弱,盡量少用
堆棧封閉:局部變量,無并發(fā)問題,在項(xiàng)目中使用最多,簡單說就是局部變量,方法的變量都拷貝到線程的堆棧中,只有這個(gè)線程能訪問到。盡量少使用全局變量(變量不是常量)
ThreadLocal線程封閉:比較好的封閉方法
ThreadLocal維護(hù)的是一個(gè)map 這個(gè)map是線程的名稱多為key 我們所有封閉的值作為value。
我們做使用Filter做登錄操作都做過,我們現(xiàn)在來使用ThreadLoad來存儲(chǔ)一下用戶信息。
public class RequestHolder { private final static ThreadLocalrequestHolder = new ThreadLocal<>(); public static void add(Long id) { requestHolder.set(id); } public static Long getId() { return requestHolder.get(); } public static void remove() { requestHolder.remove(); } }
聲明一個(gè)ThreadLoad對象用來存儲(chǔ)ThreadLoad信息。
@Slf4j public class HttpFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; log.info("do filter, {}, {}", Thread.currentThread().getId(), request.getServletPath()); RequestHolder.add(Thread.currentThread().getId()); filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { }
@Slf4j public class HttpInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("preHandle"); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { RequestHolder.remove(); log.info("afterCompletion"); return; } }
定義filter的內(nèi)容,我們在filter中將線程id加入到ThreadLoad中,然后在controller中獲取,看看能不能獲取的到。在線程執(zhí)行完之后將ThreadLoad中的數(shù)據(jù)清空防止內(nèi)存溢出。
@Controller @RequestMapping("/threadLocal") public class ThreadLocalController { @RequestMapping("/test") @ResponseBody public Long test() { return RequestHolder.getId(); } }
最后我們用postman測試發(fā)現(xiàn)打印了線程id,ThreadLoad中變量值只要是一個(gè)線程中不管在哪個(gè)類中都是共享的。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/74486.html
摘要:當(dāng)某個(gè)不應(yīng)該發(fā)布的對象被發(fā)布時(shí),這種情況被稱為逸出。線程安全共享線程安全的對象在其內(nèi)部實(shí)現(xiàn)同步,因此多線程可以通過對象的公有接口來進(jìn)行訪問而不需要進(jìn)一步的同步。 前言 本系列博客是對《Java并發(fā)編程實(shí)戰(zhàn)》的一點(diǎn)總結(jié),本篇主要講解以下幾個(gè)內(nèi)容,內(nèi)容會(huì)比較枯燥。可能大家看標(biāo)題不能能直觀的感受出到底什么意思,這就是專業(yè)術(shù)語,哈哈,解釋下,術(shù)語(terminology)是在特定學(xué)科領(lǐng)域用...
摘要:線程封閉當(dāng)訪問共享的可變數(shù)據(jù)時(shí),通常需要使用同步。如果僅在單線程內(nèi)訪問數(shù)據(jù),就不要同步。這種技術(shù)成為線程封閉。棧封閉棧封閉是線程封閉的一種特例,在棧封閉中,只能通過局部變量才能訪問對象。,對象是正確創(chuàng)建的。 線程封閉 當(dāng)訪問共享的可變數(shù)據(jù)時(shí),通常需要使用同步。一種避免使用同步的方式就是不共享數(shù)據(jù)。如果僅在單線程內(nèi)訪問數(shù)據(jù),就不要同步。這種技術(shù)成為線程封閉(Thread Confine...
摘要:線程啟動(dòng)規(guī)則對象的方法先行發(fā)生于此線程的每一個(gè)動(dòng)作。所以局部變量是不被多個(gè)線程所共享的,也就不會(huì)出現(xiàn)并發(fā)問題。通過獲取到數(shù)據(jù),放入當(dāng)前線程處理完之后將當(dāng)前線程中的信息移除。主線程必須在啟動(dòng)其他線程后立即調(diào)用方法。 一、線程安全性 定義:當(dāng)多個(gè)線程訪問某個(gè)類時(shí),不管運(yùn)行時(shí)環(huán)境采用何種調(diào)度方式,或者這些線程將如何交替執(zhí)行,并且在主調(diào)代碼中不需要任何額外的同步或協(xié)同,這個(gè)類都能表現(xiàn)出正確的行...
摘要:什么時(shí)候會(huì)出現(xiàn)線程不安全操作并非原子。只有單個(gè)組件,且它是線程安全的。這種情況下,就是的線程安全實(shí)際是委托給了整個(gè)表現(xiàn)出了線程安全。 當(dāng)多個(gè)線程去訪問某個(gè)類時(shí),如果類會(huì)表現(xiàn)出我們預(yù)期出現(xiàn)的行為,那么可以稱這個(gè)類是線程安全的。 什么時(shí)候會(huì)出現(xiàn)線程不安全? 操作并非原子。多個(gè)線程執(zhí)行某段代碼,如果這段代碼產(chǎn)生的結(jié)果受不同線程之間的執(zhí)行時(shí)序影響,而產(chǎn)生非預(yù)期的結(jié)果,即發(fā)生了競態(tài)條件,就會(huì)...
摘要:是需要我們?nèi)ヌ幚砗芏嗍虑椋瑸榱朔乐苟嗑€程給我們帶來的安全和性能的問題下面就來簡單總結(jié)一下我們需要哪些知識點(diǎn)來解決多線程遇到的問題。 前言 不小心就鴿了幾天沒有更新了,這個(gè)星期回家咯。在學(xué)校的日子要努力一點(diǎn)才行! 只有光頭才能變強(qiáng) 回顧前面: 多線程三分鐘就可以入個(gè)門了! Thread源碼剖析 本文章的知識主要參考《Java并發(fā)編程實(shí)戰(zhàn)》這本書的前4章,這本書的前4章都是講解并發(fā)的基...
閱讀 2171·2020-06-12 14:26
閱讀 2477·2019-08-29 16:41
閱讀 1885·2019-08-29 15:28
閱讀 2448·2019-08-26 13:43
閱讀 753·2019-08-26 13:37
閱讀 2773·2019-08-23 18:13
閱讀 2791·2019-08-23 15:31
閱讀 1014·2019-08-23 14:10