1. 程式人生 > 遊戲 >《使命召喚》系列解鎖Steam國區 部分商品恢復購買

《使命召喚》系列解鎖Steam國區 部分商品恢復購買

一、ThreadPoolExecutor建構函式重要引數

  • corePoolSize : 核心執行緒數執行緒數定義了最小可以同時執行的執行緒數量。
  • maximumPoolSize : 當佇列中存放的任務達到佇列容量的時候,當前可以同時執行的執行緒數量變為最大執行緒數。
  • keepAliveTime:當執行緒池中的執行緒數量大於 corePoolSize 的時候,如果這時沒有新的任務提交,核心執行緒外的執行緒不會立即銷燬,而是會等待,直到等待的時間超過了 keepAliveTime才會被回收銷燬;
  • workQueue: 當新任務來的時候會先判斷當前執行的執行緒數量是否達到核心執行緒數,如果達到的話,新任務就會被存放在佇列中。
  • threadFactory :executor 建立新執行緒的時候會用到。
  • handler :飽和策略。

舉個例子:執行緒池:核心池大小為5,最大池大小為10,佇列為100。

因為執行緒中的請求最多會建立5個,然後任務將被新增到佇列中,直到達到100。當佇列已滿時,將建立最新的執行緒maxPoolSize,最多到10個執行緒,如果再來任務,就拒絕

二、ThreadPoolExecutor 飽和策略

如果當前同時執行的執行緒數量達到最大執行緒數量並且佇列也已經被放滿了任務時,ThreadPoolTaskExecutor 定義一些策略:

  • **ThreadPoolExecutor.AbortPolicy
    **:丟擲 RejectedExecutionException來拒絕新任務的處理。
  • **ThreadPoolExecutor.CallerRunsPolicy**:呼叫執行自己的執行緒執行任務。您不會任務請求。但是這種策略會降低對於新任務提交速度,影響程式的整體效能。另外,這個策略喜歡增加佇列容量。如果您的應用程式可以承受此延遲並且你不能任務丟棄任何一個任務請求的話,你可以選擇這個策略。
  • ThreadPoolExecutor.DiscardPolicy: 不處理新任務,直接丟棄掉。
  • ThreadPoolExecutor.DiscardOldestPolicy: 此策略將丟棄最早的未處理的任務請求。

舉個例子: Spring 通過 ThreadPoolTaskExecutor 或者我們直接通過 ThreadPoolExecutor 的建構函式建立執行緒池的時候,當我們不指定 RejectedExecutionHandler 飽和策略的話來配置執行緒池的時候預設使用的是 ThreadPoolExecutor.AbortPolicy。在預設情況下,ThreadPoolExecutor 將丟擲 RejectedExecutionException 來拒絕新來的任務 ,這代表你將丟失對這個任務的處理。 對於可伸縮的應用程式,建議使用 ThreadPoolExecutor.CallerRunsPolicy。當最大池被填滿時,此策略為我們提供可伸縮佇列。

三、執行緒池中的佇列

緩衝佇列BlockingQueue簡介:

          BlockingQueue是雙緩衝佇列。BlockingQueue內部使用兩條佇列,允許兩個執行緒同時向佇列一個儲存,一個取出操作。在保證併發安全的同時,提高了佇列的存取效率。

常用的幾種BlockingQueue:

  • ArrayBlockingQueue(int i):規定大小的BlockingQueue,其構造必須指定大小。其所含的物件是FIFO順序排序的。

  • LinkedBlockingQueue()或者(int i):大小不固定的BlockingQueue,若其構造時指定大小,生成的BlockingQueue有大小限制,不指定大小,其大小有Integer.MAX_VALUE來決定。其所含的物件是FIFO順序排序的。

  • PriorityBlockingQueue()或者(int i):類似於LinkedBlockingQueue,但是其所含物件的排序不是FIFO,而是依據物件的自然順序或者建構函式的Comparator決定。

  • SynchronizedQueue():特殊的BlockingQueue,對其的操作必須是放和取交替完成。

排隊有三種通用策略:

  • 直接提交。工作佇列的預設選項是 SynchronousQueue,它將任務直接提交給執行緒而不保持它們。在此,如果不存在可用於立即執行任務的執行緒,則試圖把任務加入佇列將失敗,因此會構造一個新的執行緒。此策略可以避免在處理可能具有內部依賴性的請求集時出現鎖。直接提交通常要求無界 maximumPoolSizes 以避免拒絕新提交的任務。當命令以超過佇列所能處理的平均數連續到達時,此策略允許無界執行緒具有增長的可能性。
  • 無界佇列。使用無界佇列(例如,不具有預定義容量的 LinkedBlockingQueue)將導致在所有 corePoolSize 執行緒都忙時新任務在佇列中等待。這樣,建立的執行緒就不會超過 corePoolSize。(因此,maximumPoolSize的值也就無效了。)當每個任務完全獨立於其他任務,即任務執行互不影響時,適合於使用無界佇列;例如,在 Web頁伺服器中。這種排隊可用於處理瞬態突發請求,當命令以超過佇列所能處理的平均數連續到達時,此策略允許無界執行緒具有增長的可能性。
  • 有界佇列。當使用有限的 maximumPoolSizes時,有界佇列(如 ArrayBlockingQueue)有助於防止資源耗盡,但是可能較難調整和控制。佇列大小和最大池大小可能需要相互折衷:使用大型佇列和小型池可以最大限度地降低 CPU 使用率、作業系統資源和上下文切換開銷,但是可能導致人工降低吞吐量。如果任務頻繁阻塞(例如,如果它們是 I/O邊界),則系統可能為超過您許可的更多執行緒安排時間。使用小型佇列通常要求較大的池大小,CPU使用率較高,但是可能遇到不可接受的排程開銷,這樣也會降低吞吐量。  

四種執行緒池所用到的佇列

  1. newCachedThreadPool():所用佇列為SynchronousQueue()
  2. newFixedThreadPool():所用佇列為LinkedBlockingQueue()
  3. newScheduledThreadPool():所用佇列為DelayedWorkQueue()
  4. newSingleThreadExecutor():所用佇列為LinkedBlockingQueue()