樂(lè)觀鎖與悲觀鎖總結(jié)
932
2022-05-29
目前瀏覽器作為web服務(wù)的客戶端訪問(wèn)者,都支持并發(fā)多線程的訪問(wèn)。例如在瀏覽器訪問(wèn)一個(gè)web服務(wù)器上的HTML頁(yè)面,此時(shí)HTML頁(yè)面中的各種資源(圖片、樣式)會(huì)被瀏覽器并發(fā)的獲取,這種并發(fā)訪問(wèn)使得用戶不至于等待圖片加載的同時(shí)也不能看到文字內(nèi)容。
客戶端既然是多線程并發(fā)訪問(wèn),那么如果服務(wù)端僅僅是單線程處理客戶端的請(qǐng)求,那么客戶端的并發(fā)訪問(wèn)將會(huì)變得毫無(wú)意義。因此,大部分的web服務(wù)器也是支持并發(fā)訪問(wèn)的。常見(jiàn)的Java web服務(wù)器有Tomcat\Netty等等。
接下來(lái)我們通過(guò)結(jié)合線程池來(lái)寫一個(gè)簡(jiǎn)單的web服務(wù)器,支持訪問(wèn)html(文本、圖片)資源。
線程池接口定義
線程池具體實(shí)現(xiàn):
其主要功能和實(shí)現(xiàn)如下
服務(wù)端監(jiān)聽客戶端的socket連接
接收到的socket連接封裝到HttpRequestHandler線程中,當(dāng)成任務(wù)提交給線程池去調(diào)度執(zhí)行
HttpRequestHandler線程的run方法主要包含靜態(tài)資源jpg圖片的讀取和輸出(字節(jié)流),HTML文本讀取和輸出(字符流),關(guān)流等操作
package com.lizba.p3.http; import com.lizba.p3.threadpool.DefaultThreadPool; import com.lizba.p3.threadpool.ThreadPool; import java.io.*; import java.net.ServerSocket; import java.net.Socket; /** *
* 簡(jiǎn)單HTTP服務(wù)器 *
* * @Author: Liziba * @Date: 2021/6/18 11:47 */ public class SimplerHttpServer { /** 設(shè)置線程池的默認(rèn)大小 */ private static ThreadPool在啟動(dòng)服務(wù)前我們需要在本地提前準(zhǔn)備資源,并將資源根目錄指給SimplerHttpServer服務(wù),我在D盤放了2張圖和一個(gè)html文件。
HTML代碼
web服務(wù)測(cè)試頁(yè)面
瀏覽器訪問(wèn)效果(后來(lái)?yè)Q成了純文字,內(nèi)容比較多,ab請(qǐng)求對(duì)HTML中的圖片不加載,瀏覽器是可以加載的)
文件大概250KB
啟動(dòng)服務(wù)代碼
package com.lizba.p3.http; import java.io.IOException; /** *
* 啟動(dòng)服務(wù) *
* * @Author: Liziba * @Date: 2021/6/18 21:40 */ public class TestHttpServer { public static void main(String[] args) throws IOException { SimplerHttpServer.setBasePath("D:\\test"); SimplerHttpServer.start(); } }測(cè)試工具
Apache HTTP server benchmarking tool(ab),簡(jiǎn)單說(shuō)明一下這個(gè)測(cè)試工具。ab是一個(gè)Apache Http服務(wù)器基準(zhǔn)測(cè)試工具。它可以測(cè)試HTTP服務(wù)器每秒最多可以處理多少請(qǐng)求。如果測(cè)試的是web應(yīng)用服務(wù),這個(gè)結(jié)果可以裝換成整個(gè)應(yīng)用每秒可以滿足多少請(qǐng)求。它的缺點(diǎn)是用途比較有限,只能針對(duì)單個(gè)URL進(jìn)行盡可能快的壓力測(cè)試。
測(cè)試內(nèi)容
使用ab分10個(gè)線程發(fā)起5000請(qǐng)求,每次測(cè)試結(jié)束后改變線程池的大小,初始大小為1,測(cè)試主要觀察的是SimplerHttpServer的響應(yīng)時(shí)間和每秒完成的查詢數(shù)量,筆者的機(jī)器(CPU(AMD Ryzen 5 3600 6-Core Processor),內(nèi)存16G)。
請(qǐng)求指令(具體參數(shù)說(shuō)明請(qǐng)看我的ab工具使用章節(jié))
ab -c 10 -n 10000 http://localhost:8888/test.html
這個(gè)表示同時(shí)處理10個(gè)線程的并發(fā)請(qǐng)求,一共請(qǐng)求10000次
測(cè)試結(jié)果
通過(guò)修改線程池的大小,執(zhí)行相同的測(cè)試語(yǔ)句來(lái)測(cè)試,web服務(wù)器的響應(yīng)情況
線程池線程數(shù)量
1
5
10
20
響應(yīng)時(shí)間(ms)
0.990
0.297
0.272
0.290
每秒查詢數(shù)量
1010.08
3367.34
3677.18
3442.95
測(cè)試完成時(shí)間(s)
9.900
2.970
2.719
2.904
總結(jié):
在上述測(cè)試結(jié)果中,可以發(fā)現(xiàn)隨著線程池的線程數(shù)目的增加,SimpleHttpServer的吞吐量不斷增加,響應(yīng)時(shí)間不斷減小,因此線程池的實(shí)際作用是十分明顯的,但是我們看到線程池中的線程由10改變?yōu)?0的時(shí)候,SimpleHttpServer的響應(yīng)時(shí)間沒(méi)有減少反而有些變大了,因此線程池中的線程數(shù)目也不是越多也好的,線程池中的線程過(guò)多,反而會(huì)給系統(tǒng)增加無(wú)故開銷,適得其反。在實(shí)際開發(fā)中,我們要根據(jù)業(yè)務(wù)具體需求,硬件資源等情況來(lái)設(shè)置線程池的大小,必要的時(shí)候也可以實(shí)現(xiàn)線程池的動(dòng)態(tài)伸縮。
Java web前端
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。