資源描述:
《線程池調(diào)整真的很重要-java開發(fā)java經(jīng)驗技巧》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫。
1、線程池調(diào)整真的很重要-編程開發(fā)技術(shù)線程池調(diào)整真的很重要木文由ImportNew-justyoung翻譯自blog.bramp.neto歡迎加入翻譯小組。轉(zhuǎn)載請見文末要求。知道嗎,你的Javaweb應(yīng)用其實是使用線程池來處理請求的。這一實現(xiàn)細節(jié)被許多人忽略,但是你遲早都需要理解線程池如何使用,以及如何正確地根據(jù)應(yīng)用調(diào)整線程池配置。這篇文章的目的是為了解釋線程模型——什么是線程池、以及怎樣正確地配置線程池。單線程模型讓我們從一些基礎(chǔ)的線程模型開始,然后再隨著線程模型的演變進行更深一步的學(xué)習。你使用的任何
2、應(yīng)用服務(wù)器或框架,如Tomcat、Dropwizard>Jetty等,它們的基木原理其實是相同的。Web服務(wù)器的最底層實際上是一個socketo這個socket監(jiān)聽并接受到達的TCP連接。一旦一個連接被建立,就可以通過這個新建立的連接讀取、解析信息,然后將這些信息包裝成一個IITTP請求。這個I1TTP請求還將被移交至web應(yīng)用程序,來完成請求的動作。我們將通過一個簡單的服務(wù)器程序來展示線程在其中所起到的作用。這個服務(wù)器程序展示了大部分應(yīng)用服務(wù)器的底層實現(xiàn)細節(jié)。讓我們以一個簡單?的單?線程web服務(wù)
3、器程序開始,它的代碼像下面這樣:ScrvcrSockctlistcncr=newScrvcrSockct(8080);try{while(true){Socketsocket二1istener.accept();try{handlcRcqucst(socket);}catch(lOExceptione){e.printStackTrace();}}}finally{listener.close();}這段代碼在8080端口上創(chuàng)建了一個ServerSocket,緊接著通過循環(huán)來監(jiān)聽和接受新到達的連接。
4、一旦連接建立,會將socket傳遞給handleRequest方法。這個方法可能會讀取該IITTP請求,處理這個請求,然后寫回一個響應(yīng)。在這個簡單的例子屮,handleRequest方法從socket屮讀取簡單的一行數(shù)據(jù),然后返回一個簡短的HTTP響應(yīng)。但是,handleRequest冇可能需要處理一些更復(fù)雜的任務(wù),例如讀數(shù)據(jù)庫或者執(zhí)行其它一些10操作。finalstaticStringresponse-"IITTP/l.02000Krn〃+"Content-type:text/plainrnz,+
5、〃〃rn+“HelloWorldrn,z;publicstaticvoidhandleRequest(Socketsocket)throwsIOException{//Readtheinputstream,andreturn〃2000K〃try{BufferedReaderin二newBufferedReader(newInputStreamReader(socket,getlnputStream()));log.info(in.readLineO);OutputStreamout二socket.g
6、etOutputStream();out.write(response.getBytes(StandardCharsets.UTF_8));}fineilly{socket.closeO;}}因為只有一個線程處理所有的socket,因此只有在完全處理好一個請求后,才能再接受下一個請求。在實際的應(yīng)用中,handleRequest方法口J能需要經(jīng)過100毫秒才能返回,那么這個服務(wù)器程序在一秒中,只能按順序處理10個請求。多線程模型盡管handleRequesI可能會被10操作阻塞,CPU卻可能是空閑的,
7、它可以處理其它更多請求,但這對單線程模型來說是不能實現(xiàn)的。I大I此,通過創(chuàng)建多個線程,可以使服務(wù)器程序?qū)崿F(xiàn)并發(fā)操作:publicstaticclassHandleRequestRurrnableimplementsRurrnable{finalSocketsocket;publicHandleRequestRurrnable(Socketsocket){this.socket二socket;}publicvoidrun(){try{handleRequest(socket);}catch(IOExc
8、eptione){e.printStackTrace();}}}//MainloophereServerSocket1istener二newServerSocket(8080);try{while(true){Socketsocket=listener.accept。;newThread(newHandleRequestRunnable(socket)).start();}}finally{listenet,close();}上面這段代碼中,accept0方法仍然是在