




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
publicclassQueryIdActionpublicvoidexecute(Contextcontext)trytrylongid=}(InterruptedException{}}}//執(zhí)行方publicclassExecutionTaskimplementsRunnableprivateQueryNameActionqueryNameAction=newprivateQueryIdActionqueryIdAction=newpublicvoidrun()finalContextcontext=newSystem.out.println("ThenamequerySystem.out.println("TheidquerySystem.out.println("TheNameis"+context.getName()"and}}publicstaticvoidmain(String[]args)72
IntStream.range(1,5).forEach(i->newThread(newContextTest().new}執(zhí)行結(jié)果代ThenamequeryThenamequeryThenamequeryThenamequeryTheidqueryTheidqueryTheidqueryTheidqueryTheNameisThread-1andidTheNameisThread-2andidTheNameisThread-3andidTheNameisThread-0andid然而這種方式太笨拙了,每次調(diào)用方法時,都需要傳入Context為參數(shù),而且影響一些除了以上這些方法,其實我們還可以使用ThreadLocal實現(xiàn)上下文。ThreadLocal是線程本地變量,可以實現(xiàn)多線程的數(shù)據(jù)。ThreadLocal為每一個使用該變量的線程都提供一份獨立的副本,線程間的數(shù)據(jù)是的,每一個線程只能各自內(nèi)部的副本變量。ThreadLocal中有三個常用的方法:set、get、initialValue,我們可以通過以下一個簡單的例子來看看ThreadLocal的使用:代privatevoidtestThreadLocal()Threadt=newThread()ThreadLocal<String>mStringThreadLocal=new4publicvoidrun() 14接下來,我們使用ThreadLocal來重新實現(xiàn)最開始的上下文設(shè)計。你會發(fā)現(xiàn),我們在兩個方法中并沒有通過變量來傳下文,只是通過ThreadLocal獲取了當前線程的上下文信代publicclassContextTest//上下文publicstaticclassContextprivateStringprivatelong6publiclonggetId()return publicvoidsetId(longid) this.id= publicStringgetName() return publicvoidsetName(Stringname) = //上下文到ThreadLocal publicfinalstaticclassActionContext privatestaticfinalThreadLocal<Context>threadLocal=new protectedContextinitialValue() returnnew publicstaticActionContextgetActionContext() return publicContextgetContext() return //獲取ActionContext單 publicstaticclassContextHolder privatefinalstaticActionContextactionContext=new //設(shè)置上下文名publicclassQueryNameActionpublicvoidexecute()tryStringname= }catch(InterruptedExceptione) //設(shè)置上下文publicclassQueryIdActionpublicvoidexecute()trylongid=}catch(InterruptedExceptione) //執(zhí)行方publicclassExecutionTaskimplementsRunnableprivateQueryNameActionqueryNameAction=newprivateQueryIdActionqueryIdAction=new publicvoidrun() queryNameAction.execute();// System.out.println("Thenamequery queryIdAction.execute();//設(shè)置線程 System.out.println("Theidquery System.out.println("TheNameis"+ publicstaticvoidmain(String[]args)IntStream.range(1,5).forEach(i->newThread(newContextTest().new 93運行結(jié)果代ThenamequeryThenamequeryThenamequeryThenamequeryTheidqueryTheidqueryTheidqueryTheidqueryTheNameisThread-2andidTheNameisThread-0andidTheNameisThread-1andidTheNameisThread-3andidThread-Per-Message設(shè)計模式翻譯過來的意思就是每個消息一個線程的意思。例如,我們在處理Socket通信的時候,通常是一個線程處理以及I/O讀寫,如果I/O讀這個時候Thread-Per-Message模式就可以很好地解決這個問題,一個線程I/O事件,每當?shù)揭粋€I/O,則交給另一個處理線程執(zhí)行I/O操作。下面,我們還是通代//IO處publicclassServerHandlerimplementsprivateSocket4publicServerHandler(Socketsocket)this.socket= 8publicvoidrun()BufferedReaderin=PrintWriterout=Stringmsg=tryin=newBufferedReader(newout=newwhile((msg=in.readLine())!=null&&msg.length()!=0){//當連接成功后在System.out.println("serverreceived:"+ }catch(Exceptione)}finallytry}catch(IOExceptione) try}catch(Exceptione) try}catch(IOExceptione) 41代//SocketpublicclassServer3privatestaticintDEFAULT_PORT=privatestaticServerSocket6publicstaticvoidstart()throwsIOException publicstaticvoidstart(intport)throwsIOExceptionif(server!=null) try //啟動服 server=new //通過無線循環(huán)客戶端連 while(true) Socketsocket= //當有新的客戶端接入時,會執(zhí)行下 longstart= newThread(new longend= }finally
System.out.println("Spendtimeis"+(end-
if(server!=null)System.out.println服務(wù)器已關(guān)閉。");}} publicstaticvoidmain(String[]args)throws//運行服務(wù)newThread(new{publicvoidrun()try}catch(IOExceptione)}}}}以上,我們是完成了一個使用Thread-Per-Message計模式實現(xiàn)的Socket務(wù)端的代使用這種設(shè)計模式,如果遇到大的高并發(fā),就會出現(xiàn)嚴重的性能問題。如果針對每個I/O請求都創(chuàng)建一個線程來處理,在有大量請求同時進來時,就會創(chuàng)建大量線程,而此時JVM這里的Worker是工人的意思,代表在WorkerThread設(shè)計模式中,會有一些工人(線來。除了工人角色,WorkerThread設(shè)計模式中還包括了流水線和產(chǎn)品。這種設(shè)計模式相比Thread-Per-Message計模式,可以減少頻繁創(chuàng)建、銷毀線程所帶來我們可以假設(shè)一個場景來看下該模式的實現(xiàn),通過WorkerThread計模式來完成一個物假設(shè)一個物流倉庫的物流分揀流水線上有8個機器人,它們不斷從流水線上獲取包裹并對代//publicclassPackageprivateStringprivateString5publicStringgetName()return 9publicvoidsetName(Stringname)= publicStringgetAddress()return publicvoidsetAddress(Stringaddress)this.address= publicvoidexecute()System.out.println(Thread.currentThread().getName()+"executed 25//3finalstaticint3finalstaticintMAX_PACKAGE_NUM=45finalPackage[]6finalWorker[]7int8int9intPackageChannel(intworkers)this.packageQueue=newthis.head=this.tail=this.count=this.workerPool=new}voidinit()for(inti=0;i<workerPool.length;i++){workerPool[i]=newWorker("Worker-"+i,}}*switchtostartallofworkertovoidstartWorker()}synchronizedvoidput(Packagepackagereq)while(count>=packageQueue.length)try}catch(InterruptedExceptione)}}this.packageQueue[tail]=this.tail=(tail+1)%}synchronizedPackagetake()while(count<=0)try
代 }catch(InterruptedExceptione)
}Packagerequest=this.head=(this.head+1)%this.count--return}}代//publicclassWorkerextendsprivatestaticfinalRandomrandom=newprivatefinalPackageChannel5 publicWorker(Stringname,PackageChannelchannel)78this.channel=9}publicvoidrun()while(true)try}catch(InterruptedExceptione)}}}}代publicclassTestpublicstaticvoidmain(String[]args)//新建8finalPackageChannelchannel=new//開始工78915
//為流水線添加for(inti=0;i<100;i++)Packagepackagereq=newPackage();}}我們可以看到,這里有8個工人在不斷地分揀倉庫中已經(jīng)包裝好的商讀寫分離的業(yè)務(wù)場景中,則經(jīng)常會用到ThreadLocal實現(xiàn)動態(tài)切換數(shù)據(jù)源操作。但在使用ThreadLocal時,我們需要注意內(nèi)存泄漏問題,在之前的第25講中,我們已經(jīng)討論過這個當主線程處理每次請求都非常耗時時,就可能出現(xiàn)阻塞問題,這時候我們可以考慮將主線程業(yè)務(wù)分工到新的業(yè)務(wù)線程中,從而提高系統(tǒng)的并行處理能力。而Threa-Per-Message設(shè)計模式
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 堤壩加固合同范本
- 2024-2030年中國gps導航系統(tǒng)行業(yè)市場發(fā)展監(jiān)測及投資方向研究報告
- 浙江省歷史與社會九年級人教版上冊 2.2.1 土耳其凱末爾革命 教學設(shè)計
- 2025年度礦業(yè)權(quán)抵押貸款擔保與風險評估合同
- 2022-2027年中國袋泡茶行業(yè)市場深度分析及投資戰(zhàn)略咨詢報告
- 2025年度車展場地租賃合同(汽車改裝及配件交易)
- 6 體驗造紙 教學設(shè)計-2024-2025學年科學二年級上冊冀人版
- 自行車存放服務(wù)行業(yè)市場發(fā)展及發(fā)展趨勢與投資戰(zhàn)略研究報告
- 2025年生物科技產(chǎn)品區(qū)域代理銷售及市場開發(fā)合同
- 某鎮(zhèn)飲用水源地保護工程可行性研究報告
- 2025年中華工商時報社事業(yè)單位招聘12人歷年高頻重點模擬試卷提升(共500題附帶答案詳解)
- 安全生產(chǎn)事故調(diào)查與案例分析(第3版)課件 呂淑然 第1-4章 緒論-應急預案編制與應急管理
- 《教育強國建設(shè)規(guī)劃綱要(2024-2035年)》解讀講座
- 2024-2025學年廣東省深圳市寶安區(qū)高一(上)期末數(shù)學試卷(含答案)
- 畜禽養(yǎng)殖場惡臭污染物排放及其處理技術(shù)研究進展
- 同濟大學《線性代數(shù)》-課件
- 新生兒常見的產(chǎn)傷及護理
- 申請兩癌補助申請書
- 香港審計合同范例
- 2024年事業(yè)單位考試(面試)試題與參考答案
- 《高層建筑結(jié)構(gòu)》課件
評論
0/150
提交評論