版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第SpringBoot父子線程數(shù)據(jù)傳遞的五種方案介紹目錄方案1.ThreadLocal+TaskDecorator方案2.RequestContextHolder+TaskDecorator方案3.MDC+TaskDecorator方案4.InheritableThreadLocal方案5.TransmittableThreadLocal方案對(duì)比簡(jiǎn)答說一下InheritableThreadLocal總結(jié)
方案1.ThreadLocal+TaskDecorator
用戶工具類UserUtils
/**
*使用ThreadLocal存儲(chǔ)共享的數(shù)據(jù)變量,如登錄的用戶信息
publicclassUserUtils{
privatestaticfinalThreadLocalStringuserLocal=newThreadLocal();
publicstaticStringgetUserId(){
returnuserLocal.get();
publicstaticvoidsetUserId(StringuserId){
userLocal.set(userId);
publicstaticvoidclear(){
userLocal.remove();
}
自定義CustomTaskDecorator
/**
*線程池修飾類
publicclassCustomTaskDecoratorimplementsTaskDecorator{
@Override
publicRunnabledecorate(Runnablerunnable){
//獲取主線程中的請(qǐng)求信息(我們的用戶信息也放在里面)
StringrobotId=UserUtils.getUserId();
System.out.println(robotId);
return()-{
try{
//將主線程的請(qǐng)求信息,設(shè)置到子線程中
UserUtils.setUserId(robotId);
//執(zhí)行子線程,這一步不要忘了
runnable.run();
}finally{
//線程結(jié)束,清空這些信息,否則可能造成內(nèi)存泄漏
UserUtils.clear();
}
ExecutorConfig
在原來的基礎(chǔ)上增加executor.setTaskDecorator(newCustomTaskDecorator());
@Bean(name="asyncServiceExecutor")
publicExecutorasyncServiceExecutor(){
("startasyncServiceExecutor----------------");
//ThreadPoolTaskExecutorexecutor=newThreadPoolTaskExecutor();
//使用可視化運(yùn)行狀態(tài)的線程池
ThreadPoolTaskExecutorexecutor=newVisiableThreadPoolTaskExecutor();
//配置核心線程數(shù)
executor.setCorePoolSize(corePoolSize);
//配置最大線程數(shù)
executor.setMaxPoolSize(maxPoolSize);
//配置隊(duì)列大小
executor.setQueueCapacity(queueCapacity);
//配置線程池中的線程的名稱前綴
executor.setThreadNamePrefix(namePrefix);
//rejection-policy:當(dāng)pool已經(jīng)達(dá)到maxsize的時(shí)候,如何處理新任務(wù)
//CALLER_RUNS:不在新線程中執(zhí)行任務(wù),而是有調(diào)用者所在的線程來執(zhí)行
executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy());
//增加線程池修飾類
executor.setTaskDecorator(newCustomTaskDecorator());
//增加MDC的線程池修飾類
//executor.setTaskDecorator(newMDCTaskDecorator());
//執(zhí)行初始化
executor.initialize();
("endasyncServiceExecutor------------");
returnexecutor;
}
AsyncServiceImpl
/**
*使用ThreadLocal方式傳遞
*帶有返回值
*@throwsInterruptedException
@Async("asyncServiceExecutor")
publicCompletableFutureStringexecuteValueAsync2()throwsInterruptedException{
("startexecuteValueAsync");
System.out.println("異步線程執(zhí)行返回結(jié)果......+");
("endexecuteValueAsync");
returnCompletableFpletedFuture(UserUtils.getUserId());
}
Test2Controller
/**
*使用ThreadLocal+TaskDecorator的方式
*@return
*@throwsInterruptedException
*@throwsExecutionException
@GetMapping("/test2")
publicStringtest2()throwsInterruptedException,ExecutionException{
UserUtils.setUserId("123456");
CompletableFutureStringcompletableFuture=asyncService.executeValueAsync2();
Strings=completableFuture.get();
returns;
}
方案2.RequestContextHolder+TaskDecorator
自定義CustomTaskDecorator
/**
*線程池修飾類
publicclassCustomTaskDecoratorimplementsTaskDecorator{
@Override
publicRunnabledecorate(Runnablerunnable){
//獲取主線程中的請(qǐng)求信息(我們的用戶信息也放在里面)
RequestAttributesattributes=RequestContextHolder.getRequestAttributes();
return()-{
try{
//將主線程的請(qǐng)求信息,設(shè)置到子線程中
RequestContextHolder.setRequestAttributes(attributes);
//執(zhí)行子線程,這一步不要忘了
runnable.run();
}finally{
//線程結(jié)束,清空這些信息,否則可能造成內(nèi)存泄漏
RequestContextHolder.resetRequestAttributes();
}
ExecutorConfig
在原來的基礎(chǔ)上增加executor.setTaskDecorator(newCustomTaskDecorator());
@Bean(name="asyncServiceExecutor")
publicExecutorasyncServiceExecutor(){
("startasyncServiceExecutor----------------");
//ThreadPoolTaskExecutorexecutor=newThreadPoolTaskExecutor();
//使用可視化運(yùn)行狀態(tài)的線程池
ThreadPoolTaskExecutorexecutor=newVisiableThreadPoolTaskExecutor();
//配置核心線程數(shù)
executor.setCorePoolSize(corePoolSize);
//配置最大線程數(shù)
executor.setMaxPoolSize(maxPoolSize);
//配置隊(duì)列大小
executor.setQueueCapacity(queueCapacity);
//配置線程池中的線程的名稱前綴
executor.setThreadNamePrefix(namePrefix);
//rejection-policy:當(dāng)pool已經(jīng)達(dá)到maxsize的時(shí)候,如何處理新任務(wù)
//CALLER_RUNS:不在新線程中執(zhí)行任務(wù),而是有調(diào)用者所在的線程來執(zhí)行
executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy());
//增加線程池修飾類
executor.setTaskDecorator(newCustomTaskDecorator());
//增加MDC的線程池修飾類
//executor.setTaskDecorator(newMDCTaskDecorator());
//執(zhí)行初始化
executor.initialize();
("endasyncServiceExecutor------------");
returnexecutor;
}
AsyncServiceImpl
/**
*使用RequestAttributes獲取主線程傳遞的數(shù)據(jù)
*@return
*@throwsInterruptedException
@Async("asyncServiceExecutor")
publicCompletableFutureStringexecuteValueAsync3()throwsInterruptedException{
("startexecuteValueAsync");
System.out.println("異步線程執(zhí)行返回結(jié)果......+");
RequestAttributesattributes=RequestContextHolder.getRequestAttributes();
ObjectuserId=attributes.getAttribute("userId",0);
("endexecuteValueAsync");
returnCompletableFpletedFuture(userId.toString());
}
Test2Controller
/**
*RequestContextHolder+TaskDecorator的方式
*@return
*@throwsInterruptedException
*@throwsExecutionException
@GetMapping("/test3")
publicStringtest3()throwsInterruptedException,ExecutionException{
RequestAttributesattributes=RequestContextHolder.getRequestAttributes();
attributes.setAttribute("userId","123456",0);
CompletableFutureStringcompletableFuture=asyncService.executeValueAsync3();
Strings=completableFuture.get();
returns;
}
方案3.MDC+TaskDecorator
自定義MDCTaskDecorator
/**
*線程池修飾類
publicclassMDCTaskDecoratorimplementsTaskDecorator{
@Override
publicRunnabledecorate(Runnablerunnable){
//獲取主線程中的請(qǐng)求信息(我們的用戶信息也放在里面)
StringuserId=MDC.get("userId");
MapString,StringcopyOfContextMap=MDC.getCopyOfContextMap();
System.out.println(copyOfContextMap);
return()-{
try{
//將主線程的請(qǐng)求信息,設(shè)置到子線程中
MDC.put("userId",userId);
//執(zhí)行子線程,這一步不要忘了
runnable.run();
}finally{
//線程結(jié)束,清空這些信息,否則可能造成內(nèi)存泄漏
MDC.clear();
}
ExecutorConfig
在原來的基礎(chǔ)上增加executor.setTaskDecorator(newMDCTaskDecorator());
@Bean(name="asyncServiceExecutor")
publicExecutorasyncServiceExecutor(){
("startasyncServiceExecutor----------------");
//ThreadPoolTaskExecutorexecutor=newThreadPoolTaskExecutor();
//使用可視化運(yùn)行狀態(tài)的線程池
ThreadPoolTaskExecutorexecutor=newVisiableThreadPoolTaskExecutor();
//配置核心線程數(shù)
executor.setCorePoolSize(corePoolSize);
//配置最大線程數(shù)
executor.setMaxPoolSize(maxPoolSize);
//配置隊(duì)列大小
executor.setQueueCapacity(queueCapacity);
//配置線程池中的線程的名稱前綴
executor.setThreadNamePrefix(namePrefix);
//rejection-policy:當(dāng)pool已經(jīng)達(dá)到maxsize的時(shí)候,如何處理新任務(wù)
//CALLER_RUNS:不在新線程中執(zhí)行任務(wù),而是有調(diào)用者所在的線程來執(zhí)行
executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy());
//增加MDC的線程池修飾類
executor.setTaskDecorator(newMDCTaskDecorator());
//執(zhí)行初始化
executor.initialize();
("endasyncServiceExecutor------------");
returnexecutor;
}
AsyncServiceImpl
/**
*使用MDC獲取主線程傳遞的數(shù)據(jù)
*@return
*@throwsInterruptedException
@Async("asyncServiceExecutor")
publicCompletableFutureStringexecuteValueAsync5()throwsInterruptedException{
("startexecuteValueAsync");
System.out.println("異步線程執(zhí)行返回結(jié)果......+");
("endexecuteValueAsync");
returnCompletableFpletedFuture(MDC.get("userId"));
}
Test2Controller
/**
*使用MDC+TaskDecorator方式
*本質(zhì)也是ThreadLocal+TaskDecorator方式
*@return
*@throwsInterruptedException
*@throwsExecutionException
@GetMapping("/test5")
publicStringtest5()throwsInterruptedException,ExecutionException{
MDC.put("userId","123456");
CompletableFutureStringcompletableFuture=asyncService.executeValueAsync5();
Strings=completableFuture.get();
returns;
}
方案4.InheritableThreadLocal
用戶工具類UserInheritableUtils
//**
*使用InheritableThreadLocal存儲(chǔ)線程之間共享的數(shù)據(jù)變量,如登錄的用戶信息
publicclassUserInheritableUtils{
privatestaticfinalInheritableThreadLocalStringuserLocal=newInheritableThreadLocal();
publicstaticStringgetUserId(){
returnuserLocal.get();
publicstaticvoidsetUserId(StringuserId){
userLocal.set(userId);
publicstaticvoidclear(){
userLocal.remove();
}
AsyncServiceImpl
/**
*使用InheritableThreadLocal獲取主線程傳遞的數(shù)據(jù)
*@return
*@throwsInterruptedException
@Async("asyncServiceExecutor")
publicCompletableFutureStringexecuteValueAsync4()throwsInterruptedException{
("startexecuteValueAsync");
System.out.println("異步線程執(zhí)行返回結(jié)果......+");
("endexecuteValueAsync");
returnCompletableFpletedFuture(UserInheritableUtils.getUserId());
}
Test2Controller
/**
*使用InheritableThreadLocal方式
*@return
*@throwsInterruptedException
*@throwsExecutionException
@GetMapping("/test4")
publicStringtest4(@RequestParam("userId")StringuserId)throwsInterruptedException,ExecutionException{
UserInheritableUtils.setUserId(userId);
CompletableFutureStringcompletableFuture=asyncService.executeValueAsync4();
Strings=completableFuture.get();
returns;
}
方案5.TransmittableThreadLocal
用戶工具類UserTransmittableUtils
/**
*使用TransmittableThreadLocal存儲(chǔ)線程之間共享的數(shù)據(jù)變量,如登錄的用戶信息
publicclassUserTransmittableUtils{
privatestaticfinalTransmittableThreadLocalStringuserLocal=newTransmittableThreadLocal();
publicstaticStringgetUserId(){
returnuserLocal.get();
publicstaticvoidsetUserId(StringuserId){
userLocal.set(userId);
publicstaticvoidclear(){
userLocal.remove();
}
AsyncServiceImpl
/**
*使用TransmittableThreadLocal獲取主線程傳遞的數(shù)據(jù)
*@return
*@throwsInterruptedException
@Async("asyncServiceExecutor")
publicCompletableFutureStringexecuteValueAsync6()throwsInterruptedException{
("startexecuteValueAsync");
System.out.println("異步線程執(zhí)行返回結(jié)果......+");
("endexecuteValueAsync");
returnCompletableFpletedFuture(UserTransmittableUtils.getUserId());
}
Test2Controller
/**
*使用TransmittableThreadLocal方式
*@return
*@throwsInterruptedException
*@throwsExecutionException
@GetMapping("/test6")
publicStringtest6()throwsInterruptedException,ExecutionException{
UserTransmittableUtils.setUserId("123456");
CompletableFutureStringcompletableFuture=asyncService.executeValueAsync6();
Strings=completableFuture.get();
returns;
}
maven依賴
dependency
groupIdcom.a
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 《GA 557.1-2005互聯(lián)網(wǎng)上網(wǎng)服務(wù)營業(yè)場(chǎng)所信息安全管理代碼 第1部分:營業(yè)場(chǎng)所代碼》專題研究報(bào)告
- 中學(xué)學(xué)生社團(tuán)活動(dòng)交流合作制度
- 養(yǎng)老院消防演練制度
- 企業(yè)財(cái)務(wù)分析與預(yù)算管理制度
- 2026湖北省定向清華大學(xué)選調(diào)生招錄備考題庫附答案
- 2026福建泉州市南安市衛(wèi)生事業(yè)單位赴福建醫(yī)科大學(xué)招聘編制內(nèi)衛(wèi)生類人員64人備考題庫附答案
- 2026福建省面向華東理工大學(xué)選調(diào)生選拔工作備考題庫附答案
- 2026福建福州第十九中學(xué)招聘編外行政人員(勞務(wù)派遣)1人備考題庫附答案
- 2026重慶九洲智造科技有限公司招聘研發(fā)工程師10人備考題庫附答案
- 2026遼寧大連理工大學(xué)化工學(xué)院劉家旭團(tuán)隊(duì)科研助理招聘1人(自聘)參考題庫附答案
- 初中語文新課程標(biāo)準(zhǔn)與解讀課件
- 無人機(jī)裝調(diào)檢修工培訓(xùn)計(jì)劃及大綱
- 中建通風(fēng)與空調(diào)施工方案
- 高考語言運(yùn)用題型之長短句變換 學(xué)案(含答案)
- 春よ、來い(春天來了)高木綾子演奏長笛曲譜鋼琴伴奏
- ARJ21機(jī)型理論知識(shí)考試題庫(匯總版)
- 2023年婁底市建設(shè)系統(tǒng)事業(yè)單位招聘考試筆試模擬試題及答案解析
- GB/T 4623-2014環(huán)形混凝土電桿
- GB/T 32065.4-2015海洋儀器環(huán)境試驗(yàn)方法第4部分:高溫試驗(yàn)
- GB/T 16823.3-2010緊固件扭矩-夾緊力試驗(yàn)
- 中介服務(wù)費(fèi)承諾書
評(píng)論
0/150
提交評(píng)論