在高併發情況下容易出現請求丟失(實際是執行緒阻塞)的問題,原因就是介面或服務是單執行緒的,而且沒有加其他機制。
請求丟失其實就是介面阻塞造成的,而阻塞一般由於單執行緒造成的。
更正:目前主流web伺服器(如tomcat)本身就被設計成多執行緒的,對每乙個http請求伺服器都會啟動乙個執行緒來處理,這就意味著我們的介面天然就是多執行緒的。伺服器自身的配置就已經決定了能同時併發的執行緒數,所謂的執行緒阻塞其實指伺服器的執行緒阻塞。如果我們的介面執行效率比較低,速度比較慢,使用者的請求數超過伺服器的最大執行緒數時,會使得超出的請求被阻塞。如果我們的介面執行效率比較高,當前執行緒很快執行完任務,立即去響應超出的請求,超出的請求會很快得到處理而不會被阻塞,從而提高了系統的吞吐量和qps/tps
解決這個問題有兩種方法:
(1)使用多執行緒(執行緒池)。
每次接受乙個請求都建立乙個執行緒來處理,好處是併發性好,能及時處理,不會丟失請求;缺點是如果每次請求都建立新執行緒會造成資源消耗。
解決方法:使用執行緒池,配置好執行緒池引數,可以將資源消耗控制在一定範圍。
(2)使用快取或佇列。
如果一定要用單執行緒方式處理請求,並且不造成阻塞,可以使用快取或佇列。
這種方式也就是使用單執行緒實現多執行緒的方式。
第一種方法使用執行緒池來執行非同步任務,可以在一定程度上提高介面執行效率,降低執行緒阻塞的風險;
第二種方法不能避免執行緒阻塞,反而加大了執行緒阻塞的風險。因為在迴圈內部並沒有啟動非同步執行緒來處理,所有的任務都是在當前介面裡完成的,甚至當先執行緒要迴圈處理佇列中的所有請求,所以反而加大了執行緒阻塞的風險。
除非在迴圈內部啟動非同步執行緒來處理,但這沒有必要,因為執行緒池本身就有任務佇列來管理,在介面裡再設定任務佇列沒有必要。
與其再花1ms來設定任務佇列,不如直接把任務提交給執行緒池來處理,讓執行緒池來管理任務。
所以,對於這種執行緒阻塞的問題,要麼優化介面執行效率,要麼使用執行緒池,沒有其他太好的辦法。
執行緒的阻塞
一 等待阻塞 執行的執行緒呼叫了wait 方法,會釋放鎖,jvm會將該執行緒到等待佇列中。二 同步阻塞 執行緒在執行過程中,獲取物件的同步鎖,發現這個同步鎖在被其他執行緒占用,則jvm會將該執行緒放入鎖池 lock pool 中。三 其他阻塞 執行的執行緒執行join或者sleep方法 wait方法...
併發,同步,非同步,阻塞,非阻塞,執行緒
乙個cpu沒有真正意義的併發,兩個人同時做同樣的事情才是真正意義上的併發,只有統籌分時處理.多路同步 同步,實時處理並且活動按順序執行 非同步,乙個人合理的安排時間來做事情,分時處理,活動分段執行,非順序執行 阻塞模式,等,同步,併發,非同步都有可能會阻塞,只是機率的大小 非阻塞模式 不等 併發,併...
程序與執行緒 阻塞與非阻塞
程序 cpu執行任務的模組。執行緒 模組中的最小單元。cpu比作我們每個人,到飯點吃飯了。可以點很多菜 cpu中的程序 宮保雞丁,魚香肉絲,酸辣土豆絲。每樣菜具體包含了哪些內容 cpu每個程序中的執行緒 宮保雞丁 詳情 黃瓜 胡蘿蔔 雞肉 花生公尺 而詳情構成了宮保雞丁這道菜,吃了以後不餓。就可以幹...