溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

java線程池的keepAliveTime的作用是什么

發(fā)布時間:2021-02-18 13:57:58 來源:億速云 閱讀:650 作者:Leah 欄目:開發(fā)技術(shù)

本篇文章給大家分享的是有關(guān)java線程池的keepAliveTime的作用是什么,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

keepAliveTime的jdk中的解釋為:

當(dāng)線程數(shù)大于核心時,此為終止前多余的空閑線程等待新任務(wù)的最長時間。

說的讓人感覺比較模糊,總結(jié)一下大概意思為:比如說線程池中最大的線程數(shù)為50,而其中只有40個線程任務(wù)在跑,相當(dāng)于有10個空閑線程,這10個空閑線程不能讓他一直在開著,因為線程的存在也會特別好資源的,所有就需要設(shè)置一個這個空閑線程的存活時間,這么解釋應(yīng)該就很清楚了。

這樣以后忘記了就過來看看就OK了。

補充:線程池的狀態(tài)及KeepAliveTime參數(shù)

五個狀態(tài)

 // runState is stored in the high-order bits
 private static final int RUNNING = -1 << COUNT_BITS;
 private static final int SHUTDOWN = 0 << COUNT_BITS;
 private static final int STOP  = 1 << COUNT_BITS;
 private static final int TIDYING = 2 << COUNT_BITS;
 private static final int TERMINATED = 3 << COUNT_BITS;

循環(huán)getTask方法

 private Runnable getTask() {
  boolean timedOut = false; // Did the last poll() time out?
  retry:
  for (;;) {
   int c = ctl.get();
   int rs = runStateOf(c);
   // Check if queue empty only if necessary.
   if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
    decrementWorkerCount();
    return null;
   }
   boolean timed;  // Are workers subject to culling?
   for (;;) {
    int wc = workerCountOf(c);
    timed = allowCoreThreadTimeOut || wc > corePoolSize;
    //默認allowCoreThreadTimeOut為false,除非程序指定
    //(1)當(dāng)沒有超過核心線程時,默認allowCoreThreadTimeOut為false時
    //timed值為false,始終break掉,不會銷毀線程
    //(2)當(dāng)超過核心線程數(shù),默認allowCoreThreadTimeOut為false時
    //timed值為true,如果超過最大值,則銷毀;如果timeout過,則銷毀
    // 如果allowCoreThreadTimeOut為true,則timed始終為true
    if (wc <= maximumPoolSize && ! (timedOut && timed))
     break;
    if (compareAndDecrementWorkerCount(c))
     return null;
    c = ctl.get(); // Re-read ctl
    if (runStateOf(c) != rs)
     continue retry;
    // else CAS failed due to workerCount change; retry inner loop
   }
   try {
    Runnable r = timed ?
     workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
     workQueue.take();
    if (r != null)
     return r;
    timedOut = true;
   } catch (InterruptedException retry) {
    timedOut = false;
   }
  }
 }

線程池狀態(tài)大于SHUTDOWN值的兩種情況

1、調(diào)用shutdown方法

當(dāng)線程池調(diào)用了shutdown方法,線程池的狀態(tài)會首先被設(shè)置為SHUTDOWN,然后遍歷線程池中所有線程,調(diào)用一次interrupt方法,如果在休眠中的線程將會激活,激活后的線程以及調(diào)用shutdown方法本身的線程都會嘗試去調(diào)用tryTerminate方法,該方法將判定如果線程池中所有記錄的線程數(shù)為0,則將線程狀態(tài)改為TERMINATED,這個值為3,將大于SHUTDOWN狀態(tài)值。

2、調(diào)用shutdownNow方法

當(dāng)線程調(diào)用了shutdownNow方法后,首先將線程的狀態(tài)修改為STOP,這個狀態(tài)是大于SHUTDOWN值的,接下來它也會通過中斷激活線程,只是它來的更暴力一些,連加鎖和一些基本判斷都沒有,直接中斷;在調(diào)用tryTerminate之前會先清空阻塞隊列中所有的元素,這些元素被組裝為一個List列表作為shutdownNow方法的返回值。換句話說,沒有執(zhí)行的任務(wù)在shutdownNow執(zhí)行后的返回值中可以得到。在程序某些必要的情況下,可以通過線程池的isTerminating,isTerminated,isStopped,isShutdown來對線程做一些狀態(tài)判定。

KeepAliveTime參數(shù)

workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS)

當(dāng)阻塞隊列中沒有任務(wù)時,等待時間達到keepAliveTime毫秒值時就會被自動喚醒,而不會永遠地沉睡下去。

keepAliveTime,如果是通過newCachedThreadPool的話,默認是1分鐘超時,如果遇到前面所提到的瞬間沖擊,那么線程池數(shù)量將瞬間快速膨脹,而且這些瞬間膨脹的線程的生命周期最少在1分鐘以上。

如果設(shè)置了該參數(shù),那么當(dāng)timeout的時候,就return null,就會跳出循環(huán),回收線程。

if (wc <= maximumPoolSize && ! (timedOut && timed))
     break;
    if (compareAndDecrementWorkerCount(c))
     return null;

allowCoreThreadTimeout : 默認情況下核心線程不會退出,可通過將該參數(shù)設(shè)置為true,讓核心線程也退出。

默認的Executors工廠,只有newCachedThreadPool,timeout為60秒,出現(xiàn)timeout情況下,而且線程數(shù)超過了核心線程數(shù),會銷毀銷毀線程。保持在corePoolSize數(shù)(如果是cached的,corePoolSize為0)。

 /**
  * Timeout in nanoseconds for idle threads waiting for work.
  * Threads use this timeout when there are more than corePoolSize
  * present or if allowCoreThreadTimeOut. Otherwise they wait
  * forever for new work.
  */
 private volatile long keepAliveTime;
 /**
  * If false (default), core threads stay alive even when idle.
  * If true, core threads use keepAliveTime to time out waiting
  * for work.
  */
 private volatile boolean allowCoreThreadTimeOut;

線程池最小是corePoolSize,最大是maximumPoolSize,除非設(shè)置了allowCoreThreadTimeOut和超時時間,這種情況線程數(shù)可能減少到0,最大可能是Integer.MAX_VALUE。

Core pool size is the minimum number of workers to keep alive(and not allow to time out etc) unless allowCoreThreadTimeOut is set, in which case the minimum is zero.

/**
  * Creates a thread pool that creates new threads as needed, but
  * will reuse previously constructed threads when they are
  * available. These pools will typically improve the performance
  * of programs that execute many short-lived asynchronous tasks.
  * Calls to <tt>execute</tt> will reuse previously constructed
  * threads if available. If no existing thread is available, a new
  * thread will be created and added to the pool. Threads that have
  * not been used for sixty seconds are terminated and removed from
  * the cache. Thus, a pool that remains idle for long enough will
  * not consume any resources. Note that pools with similar
  * properties but different details (for example, timeout parameters)
  * may be created using {@link ThreadPoolExecutor} constructors.
  *
  * @return the newly created thread pool
  */
 public static ExecutorService newCachedThreadPool() {
  return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
          60L, TimeUnit.SECONDS,
          new SynchronousQueue<Runnable>());
 }
 /**
  * Creates a thread pool that creates new threads as needed, but
  * will reuse previously constructed threads when they are
  * available, and uses the provided
  * ThreadFactory to create new threads when needed.
  * @param threadFactory the factory to use when creating new threads
  * @return the newly created thread pool
  * @throws NullPointerException if threadFactory is null
  */
 public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
  return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
          60L, TimeUnit.SECONDS,
          new SynchronousQueue<Runnable>(),
          threadFactory);
 }

超時timeout設(shè)置為0的話,表示不等待

public E poll(long timeout, TimeUnit unit) throws InterruptedException {
  return pollFirst(timeout, unit);
 }

具體如下

public E pollFirst(long timeout, TimeUnit unit)
  throws InterruptedException {
  long nanos = unit.toNanos(timeout);
  final ReentrantLock lock = this.lock;
  lock.lockInterruptibly();
  try {
   E x;
   while ( (x = unlinkFirst()) == null) {
    if (nanos <= 0)
     return null;
    nanos = notEmpty.awaitNanos(nanos);
   }
   return x;
  } finally {
   lock.unlock();
  }
 }

以上就是java線程池的keepAliveTime的作用是什么,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI