java并發(fā)編程學習的一些總結


1.不應用線程池的缺點

  • 有些開發(fā)者圖省事,遇到需要多線程處理的地方,直接new Thread(...).start(),對于一般場景是沒問題的,但如果是在并發(fā)請求很高的情況下,就會有些隱患:
  • 新建線程的開銷。線程雖然比進程要輕量許多,但對于JVM來說,新建一個線程的代價還是挺大的,決不同于新建一個對象
  • 資源消耗量。沒有一個池來限制線程的數(shù)量,會導致線程的數(shù)量直接取決于應用的并發(fā)量,這樣有潛在的線程數(shù)據(jù)巨大的可能,那么資源消耗量將是巨大的
  • 穩(wěn)定性。當線程數(shù)量超過系統(tǒng)資源所能承受的程度,穩(wěn)定性就會成問題

2.制定執(zhí)行策略

  • 在每個需要多線程處理的地方,不管并發(fā)量有多大,需要考慮線程的執(zhí)行策略
  • 任務以什么順序執(zhí)行
  • 可以有多少個任務并發(fā)執(zhí)行
  • 可以有多少個任務進入等待執(zhí)行隊列
  • 系統(tǒng)過載的時候,應該放棄哪些任務?如何通知到應用程序?
  • 一個任務的執(zhí)行前后應該做什么處理

3.線程池的類型

  • 不管是通過Executors創(chuàng)建線程池,還是通過Spring來管理,都得清楚知道有哪幾種線程池:
    • FixedThreadPool:定長線程池,提交任務時創(chuàng)建線程,直到池的最大容量,如果有線程非預期結束,會補充新線程
    • CachedThreadPool:可變線程池,它猶如一個彈簧,如果沒有任務需求時,它回收空閑線程,如果需求增加,則按需增加線程,不對池的大小做限制
    • SingleThreadExecutor:單線程。處理不過來的任務會進入FIFO隊列等待執(zhí)行
    • SecheduledThreadPool:周期性線程池。支持執(zhí)行周期性線程任務
  • 其實,這些不同類型的線程池都是通過構建一個ThreadPoolExecutor來完成的,所不同的是corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory這么幾個參數(shù)。具體可以參見JDK DOC。

4.線程池飽和策略

  • 由以上線程池類型可知,除了CachedThreadPool其他線程池都有飽和的可能,當飽和以后就需要相應的策略處理請求線程的任務,比如,達到上限時通過ThreadPoolExecutor.setRejectedExecutionHandler方法設置一個拒絕任務的策略,JDK提供了AbortPolicy、CallerRunsPolicy、DiscardPolicy、DiscardOldestPolicy幾種策略,具體差異可見JDK DOC

5.線程無依賴性

  • 多線程任務設計上盡量使得各任務是獨立無依賴的,所謂依賴性可兩個方面:
    • 線程之間的依賴性。如果線程有依賴可能會造成死鎖或饑餓
    • 調(diào)用者與線程的依賴性。調(diào)用者得監(jiān)視線程的完成情況,影響可并發(fā)量
      當然,在有些業(yè)務里確實需要一定的依賴性,比如調(diào)用者需要得到線程完成后結果,傳統(tǒng)的Thread是不便完成的,因為run方法無返回值,只能通過一些共享的變量來傳遞結果,但在Executor框架里可以通過Future和Callable實現(xiàn)需要有返回值的任務,當然線程的異步性導致需要有相應機制來保證調(diào)用者能等待任務完成。
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容