從0到1構建分佈式秒殺系統案例的代碼已經所有上傳至碼雲,文章也被分發到各個平臺。其中也收到了很多小夥伴喜歡和反饋,有網友如是說:java
說實話,能用上的很少,中小企業都不可能用到,大型企業也不是一我的就能搞起的,大部分人一生都用不上,等有這個須要再搞吧。git
個人觀點是贊同但不支持,基本上任何事物都是呈金字塔分佈,互聯網也不例外,也就是說大部分可能都是普通人,接觸不到所謂大廠的應用場景。可是,書到用時方恨少,機會老是留給有準備的人的,除非有錢難買我樂意,只能說大千世界,每一個人都有本身的生活方式,尊重並活着。算法
前面都是扯淡,也不是什麼鋪墊,在聊線程池以前咱們最好簡單瞭解下什麼是進程,什麼是線程,進程和線程到底有什麼區別?spring
這裏咱們,搬運下某百科的釋義:數據庫
進程是計算機中的程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操做系統結構的基礎。在早期面向進程設計的計算機結構中,進程是程序的基本執行實體;在當代面向線程設計的計算機結構中,進程是線程的容器。程序是指令、數據及其組織形式的描述,進程是程序的實體。tomcat
固然,知乎上也有很多網友的回答,每一個人都有本身不一樣的理解方式。這裏咱們拿Tomcat容器作例子:你能夠這麼理解,運行中的Tomcat容器就是一個進程,而每一個用戶的操做(查詢、上傳)能夠當作一個或者多個線程。服務器
秒殺活動中,瞬時併發是很是大的,若是每個請求都開啓一個新線程,系統就要不斷的進行線程的建立和銷燬,有時花在建立和銷燬線程上的時間會比線程真正執行的時間還長。而且因爲硬件條件限制,線程數量又不能無限建立。網絡
那麼線程池到底解決了那些問題:併發
調用ThreadPoolExecutor的execute提交線程,首先檢查CorePool,若是CorePool內的線程小於CorePoolSize,新建立線程執行任務。分佈式
若是當前CorePool內的線程大於等於CorePoolSize,那麼將線程加入到BlockingQueue。
若是不能加入BlockingQueue,在小於MaxPoolSize的狀況下建立線程執行任務。
若是線程數大於等於MaxPoolSize,那麼執行拒絕策略。
爲了方便測試,咱們在Control中定義了線程池,來模擬用戶秒殺動做:
定義初始線程數:
private static int corePoolSize = Runtime.getRuntime().availableProcessors();
定義Executor:
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, corePoolSize+1, 10l, TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>(1000));
workQueue則是線程池的緩衝隊列,還未執行的線程會在隊列中等待,監控隊列長度,確保隊列有界;不當的線程池大小會使得處理速度變慢,穩定性降低,而且致使內存泄露。若是配置的線程過少,則隊列會持續變大,消耗過多內存;而過多的線程又會 因爲頻繁的上下文切換致使整個系統的速度變緩——殊途而同歸。隊列的長度相當重要,它必須得是有界的,這樣若是線程池不堪重負了它能夠暫時拒絕掉新的請求。
ExecutorService 默認的實現是一個無界的LinkedBlockingQueue。
以上只是爲了測試方便,模擬出的數據。真實的生產環境,咱們要接入Nginx和Tomcat來處理用戶的請求。而Tomcat做爲一名容器也是有本身的一套鏈接池的,做爲開發人員你並不須要本身去實現。
Tomcat默認使用自帶的鏈接池,這裏咱們也能夠自定義實現,打開/conf/server.xml文件,在Connector以前配置一個線程池:
<Executor name="tomcatThreadPool" namePrefix="tomcatThreadPool-" maxThreads="1000" maxIdleTime="300000" minSpareThreads="200"/>
name:共享線程池的名字。這是Connector爲了共享線程池要引用的名字,該名字必須惟一。默認值:None;
namePrefix:在JVM上,每一個運行線程均可以有一個name 字符串。這一屬性爲線程池中每一個線程的name字符串設置了一個前綴,Tomcat將把線程號追加到這一前綴的後面。默認值:tomcat-exec-;
maxThreads:該線程池能夠容納的最大線程數。默認值:200;
maxIdleTime:在Tomcat關閉一個空閒線程以前,容許空閒線程持續的時間(以毫秒爲單位)。只有當前活躍的線程數大於minSpareThread的值,纔會關閉空閒線程。默認值:60000(一分鐘)。
minSpareThreads:Tomcat應該始終打開的最小不活躍線程數。默認值:25。
配置Connector:
<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" minProcessors="5" maxProcessors="75" acceptCount="1000"/>
executor:表示使用該參數值對應的線程池;
minProcessors:服務器啓動時建立的處理請求的線程數;
maxProcessors:最大能夠建立的處理請求的線程數;
acceptCount:指定當全部可使用的處理請求的線程數都被使用時,能夠放處處理隊列中的請求數,超過這個數的請求將不予處理。
代碼案例:從0到1構建分佈式秒殺系統