中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

大學(xué)招生網(wǎng)站建設(shè)關(guān)鍵信息基礎(chǔ)設(shè)施安全保護(hù)條例

大學(xué)招生網(wǎng)站建設(shè),關(guān)鍵信息基礎(chǔ)設(shè)施安全保護(hù)條例,小程序 appid,中國(guó)建設(shè)企業(yè)協(xié)會(huì)網(wǎng)站Java 線程池的使用,是面試必問(wèn)的。下面我們來(lái)從使用到源碼整理一下。 1、構(gòu)造線程池 通過(guò)Executors來(lái)構(gòu)造線程池 1、構(gòu)造一個(gè)固定線程數(shù)目的線程池,配置的corePoolSize與maximumPoolSize大小相同, 同時(shí)使用了一個(gè)無(wú)界LinkedBlockingQueue存…

Java 線程池的使用,是面試必問(wèn)的。下面我們來(lái)從使用到源碼整理一下。

1、構(gòu)造線程池

  • 通過(guò)Executors來(lái)構(gòu)造線程池
1、構(gòu)造一個(gè)固定線程數(shù)目的線程池,配置的corePoolSize與maximumPoolSize大小相同,
同時(shí)使用了一個(gè)無(wú)界LinkedBlockingQueue存放阻塞任務(wù),因此多余的任務(wù)將存在阻塞隊(duì)列,
不會(huì)由RejectedExecutionHandler處理 
public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}2、構(gòu)造一個(gè)緩沖功能的線程池,配置corePoolSize=0,maximumPoolSize=Integer.MAX_VALUE,
keepAliveTime=60s,以及一個(gè)無(wú)容量的阻塞隊(duì)列 SynchronousQueue,因此任務(wù)提交之后,
將會(huì)創(chuàng)建新的線程執(zhí)行;線程空閑超過(guò)60s將會(huì)銷(xiāo)毀 public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}3、構(gòu)造一個(gè)只支持一個(gè)線程的線程池,配置corePoolSize=maximumPoolSize=1,
無(wú)界阻塞隊(duì)列LinkedBlockingQueue;保證任務(wù)由一個(gè)線程串行執(zhí)行 public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));}4、構(gòu)造有定時(shí)/延時(shí)功能的線程池,配置corePoolSize,無(wú)界延遲阻塞隊(duì)列DelayedWorkQueue;
有意思的是:maximumPoolSize=Integer.MAX_VALUE,由于DelayedWorkQueue是無(wú)界隊(duì)列,
所以這個(gè)值是沒(méi)有意義的
對(duì)于一些不能及時(shí)處理,需要延時(shí)處理的操作,用ScheduledExecutorService處理很方便,
比如我們?cè)谀承l件下需要清理redis/mysql中數(shù)據(jù)時(shí),但是可能當(dāng)前有些地方還需要用到(并發(fā)),這時(shí)用ScheduledExecutorService處理非常合適,
雖然也可以用定時(shí)任務(wù)處理,但是定時(shí)任務(wù)會(huì)一直執(zhí)行,而這里的場(chǎng)景是滿足一定條件去執(zhí)行,而執(zhí)行的機(jī)會(huì)又很少。public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {return new ScheduledThreadPoolExecutor(corePoolSize);}public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory) {return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);}public ScheduledThreadPoolExecutor(int corePoolSize,ThreadFactory threadFactory) {super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,new DelayedWorkQueue(), threadFactory);}注:阻塞隊(duì)列與普通隊(duì)列的區(qū)別在于,當(dāng)隊(duì)列是空的時(shí),從隊(duì)列中獲取元素的操作將會(huì)被阻塞,
或者當(dāng)隊(duì)列是滿時(shí),往隊(duì)列里添加元素的操作會(huì)被阻塞。
試圖從空的阻塞隊(duì)列中獲取元素的線程將會(huì)被阻塞,直到其他的線程往空的隊(duì)列插入新的元素。
同樣,試圖往已滿的阻塞隊(duì)列中添加新元素的線程同樣也會(huì)被阻塞,直到其他的線程使隊(duì)列重新變得空閑起來(lái),
如從隊(duì)列中移除一個(gè)或者多個(gè)元素,或者完全清空隊(duì)列.
  • 通過(guò)ThreadPoolExecutor自定義線程池
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,  long keepAliveTime,TimeUnit unit,  BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,  RejectedExecutionHandler handler )
* corePoolSize 核心線程池大小----1
* maximumPoolSize 最大線程池大小----3
* keepAliveTime 線程池中超過(guò)corePoolSize數(shù)目的空閑線程最大存活時(shí)間----30
* keepAliveTime時(shí)間單位----TimeUnit.MINUTES 
* workQueue 阻塞隊(duì)列----new ArrayBlockingQueue<Runnable>(5)----阻塞隊(duì)列的容量是5
* threadFactory 新建線程工廠----new CustomThreadFactory()----定制的線程工廠 
* rejectedExecutionHandler 當(dāng)提交任務(wù)數(shù)超過(guò)maxmumPoolSize+workQueue之和(3+5),即當(dāng)提交第9個(gè)任務(wù)時(shí)(前面線程都沒(méi)有執(zhí)行完,此測(cè)試方法中用 sleep(30), 任務(wù)會(huì)交給RejectedExecutionHandler來(lái)處理 new ThreadPoolExecutor(  1,  3,  30,  TimeUnit.MINUTES,  new ArrayBlockingQueue<Runnable>(5),  new CustomThreadFactory(),  new CustomRejectedExecutionHandler());  
package com.vendor.control.web.device;import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;/*** Created by zhangkai on 2019/8/12.*/
public class CustomThreadPoolExecutor
{private ThreadPoolExecutor pool = null;public void init() {pool = new ThreadPoolExecutor(1,3,30,TimeUnit.MINUTES,new ArrayBlockingQueue<Runnable>(5),new CustomThreadFactory(),new CustomRejectedExecutionHandler());}public void destory() {if(pool != null) {pool.shutdownNow();}}public ExecutorService getCustomThreadPoolExecutor() {return this.pool;}private class CustomThreadFactory implements ThreadFactory{private AtomicInteger count = new AtomicInteger(0);@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r);String threadName = CustomThreadPoolExecutor.class.getSimpleName() + count.addAndGet(1);System.out.println(threadName);t.setName(threadName);return t;}}private class CustomRejectedExecutionHandler implements RejectedExecutionHandler {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {try {// 當(dāng)使用blockingqueue的offer插入數(shù)據(jù)時(shí),如果隊(duì)列已滿,那么阻塞指定時(shí)間等待隊(duì)列可用,
//等待期間如果被中斷,那么拋出InterruptedException。// 如果插入成功,那么返回true,如果在達(dá)到指定時(shí)間后仍然隊(duì)列不可用,
//那么返回false。===========超時(shí)退出// 使用put 時(shí),插入數(shù)據(jù)時(shí),如果隊(duì)列已滿,那么阻塞等待隊(duì)列可用,等待期間如果被中斷,
//那么拋出InterruptedException。 =============  一直阻塞:System.out.println("拒絕任務(wù)");executor.getQueue().offer(r); //會(huì)有任務(wù)線程不執(zhí)行//executor.getQueue().put(r); //不會(huì)有任務(wù)線程不執(zhí)行} catch (Exception e) {e.printStackTrace();}}}// 測(cè)試構(gòu)造的線程池public static void main(String[] args) {CustomThreadPoolExecutor exec = new CustomThreadPoolExecutor();// 1.初始化exec.init();ExecutorService pool = exec.getCustomThreadPoolExecutor();for(int i=1; i<=10; i++) {System.out.println("提交第" + i + "個(gè)任務(wù)!");pool.execute(new Runnable() {@Overridepublic void run() {try {TimeUnit.SECONDS.sleep(30);System.out.println(">>>task is running=====");} catch (InterruptedException e) {e.printStackTrace();}}});}// 2.銷(xiāo)毀----此處不能銷(xiāo)毀,因?yàn)槿蝿?wù)沒(méi)有提交執(zhí)行完,如果銷(xiāo)毀線程池,任務(wù)也就無(wú)法執(zhí)行了// exec.destory();try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}}
}

2、線程池執(zhí)行流程

源碼

 public void execute(Runnable command) {if (command == null)throw new NullPointerException();int c = ctl.get();// 1、工作線程 < 核心線程 if (workerCountOf(c) < corePoolSize) {if (addWorker(command, true))return;c = ctl.get();}// 2、運(yùn)行態(tài),并嘗試將任務(wù)加入隊(duì)列;如果能加入,說(shuō)明隊(duì)列沒(méi)滿if (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();if (! isRunning(recheck) && remove(command))reject(command);else if (workerCountOf(recheck) == 0)addWorker(null, false);} // 3、工作線程 < 核心線程,并且隊(duì)列滿了,那么繼續(xù)新建線程,嘗試使用最大線程運(yùn)行else if (!addWorker(command, false))reject(command);}

從上面這個(gè)圖中可以看出,在創(chuàng)建了線程池后,默認(rèn)情況下,線程池中并沒(méi)有任何線程,而是等待有任務(wù)到來(lái)才創(chuàng)建線程去執(zhí)行任務(wù),除非調(diào)用了prestartAllCoreThreads()或者prestartCoreThread()方法,從這2個(gè)方法的名字就可以看出,是預(yù)創(chuàng)建線程的意思,即在沒(méi)有任務(wù)到來(lái)之前就創(chuàng)建corePoolSize個(gè)線程或者一個(gè)線程。默認(rèn)情況下,在創(chuàng)建了線程池后,線程池中的線程數(shù)為0,當(dāng)有任務(wù)來(lái)之后,并且工作線程數(shù)<核心線程數(shù)時(shí),就會(huì)創(chuàng)建一個(gè)線程去執(zhí)行任務(wù),當(dāng)線程池中的線程數(shù)目達(dá)到corePoolSize后,就會(huì)把到達(dá)的任務(wù)放到緩存隊(duì)列當(dāng)中;
在核心線程數(shù)創(chuàng)建以后,就不會(huì)再關(guān)閉了,這個(gè)創(chuàng)建過(guò)程類(lèi)似懶加載,只有需要用的時(shí)候才去創(chuàng)建

當(dāng)核心線程數(shù)執(zhí)行完其第一個(gè)任務(wù)以后,就會(huì)阻塞,等待從隊(duì)列中獲取任務(wù)(getTask),獲取到的話,線程就繼續(xù)執(zhí)行任務(wù)。見(jiàn)下面runWorker源碼。

ThreadPoolExecutor執(zhí)行順序總結(jié):
當(dāng)線程數(shù)小于核心線程數(shù)時(shí),創(chuàng)建線程。
當(dāng)線程數(shù)大于等于核心線程數(shù),且任務(wù)隊(duì)列未滿時(shí),將任務(wù)放入任務(wù)隊(duì)列。
當(dāng)線程數(shù)大于等于核心線程數(shù),且任務(wù)隊(duì)列已滿
若線程數(shù)小于最大線程數(shù),創(chuàng)建線程
若線程數(shù)等于最大線程數(shù),拋出異常,拒絕任務(wù)

簡(jiǎn)單的說(shuō),

  • addWorker(command, true): 創(chuàng)建核心線程執(zhí)行任務(wù);
  • addWorker(command, false):創(chuàng)建非核心線程執(zhí)行任務(wù);
  • addWorker(null, false): 創(chuàng)建非核心線程,當(dāng)前任務(wù)為空;
  • addWorker(null,true) : 預(yù)先創(chuàng)建corePoolSize個(gè)線程;

addWorker源碼

    private boolean addWorker(Runnable firstTask, boolean core) {retry:for (;;) {int c = ctl.get();int rs = runStateOf(c);// Check if queue empty only if necessary.if (rs >= SHUTDOWN &&! (rs == SHUTDOWN &&firstTask == null &&! workQueue.isEmpty()))return false;for (;;) {int wc = workerCountOf(c);if (wc >= CAPACITY ||wc >= (core ? corePoolSize : maximumPoolSize))return false;if (compareAndIncrementWorkerCount(c))break retry;c = ctl.get();  // Re-read ctlif (runStateOf(c) != rs)continue retry;// else CAS failed due to workerCount change; retry inner loop}}boolean workerStarted = false;boolean workerAdded = false;Worker w = null;try {w = new Worker(firstTask);final Thread t = w.thread;if (t != null) {final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {// Recheck while holding lock.// Back out on ThreadFactory failure or if// shut down before lock acquired.int rs = runStateOf(ctl.get());if (rs < SHUTDOWN ||(rs == SHUTDOWN && firstTask == null)) {if (t.isAlive()) // precheck that t is startablethrow new IllegalThreadStateException();workers.add(w);int s = workers.size();if (s > largestPoolSize)largestPoolSize = s;workerAdded = true;}} finally {mainLock.unlock();}if (workerAdded) {//啟動(dòng)線程,執(zhí)行任務(wù),這里調(diào)用的其實(shí)是worker的run方法,見(jiàn)下面Worker構(gòu)造方法t.start();workerStarted = true;}}} finally {if (! workerStarted)addWorkerFailed(w);}return workerStarted;}//Worker構(gòu)造方法,thread變量構(gòu)造的線程是它本身,即當(dāng)調(diào)用Worker中thread.start()時(shí),
//最終執(zhí)行的是Worker類(lèi)的run方法Worker(Runnable firstTask) {setState(-1); // inhibit interrupts until runWorkerthis.firstTask = firstTask;this.thread = getThreadFactory().newThread(this);}//執(zhí)行任務(wù)時(shí),最后調(diào)用的方法final void runWorker(Worker w) {Thread wt = Thread.currentThread();Runnable task = w.firstTask;w.firstTask = null;w.unlock(); // allow interruptsboolean completedAbruptly = true;try {//第一次執(zhí)行task時(shí),task肯定不為空,當(dāng)firstTask執(zhí)行完以后,while循環(huán)等待,//指導(dǎo)從隊(duì)列中獲取到task,即getTask()不為空時(shí),getTask就是從隊(duì)列中獲取任務(wù)while (task != null || (task = getTask()) != null) {w.lock();// If pool is stopping, ensure thread is interrupted;// if not, ensure thread is not interrupted.  This// requires a recheck in second case to deal with// shutdownNow race while clearing interruptif ((runStateAtLeast(ctl.get(), STOP) ||(Thread.interrupted() &&runStateAtLeast(ctl.get(), STOP))) &&!wt.isInterrupted())wt.interrupt();try {beforeExecute(wt, task);Throwable thrown = null;try {task.run();} catch (RuntimeException x) {thrown = x; throw x;} catch (Error x) {thrown = x; throw x;} catch (Throwable x) {thrown = x; throw new Error(x);} finally {afterExecute(task, thrown);}} finally {task = null;w.completedTasks++;w.unlock();}}completedAbruptly = false;} finally {processWorkerExit(w, completedAbruptly);}}

3、拒絕策略

當(dāng)線程池的任務(wù)緩存隊(duì)列已滿并且線程池中的線程數(shù)目達(dá)到maximumPoolSize時(shí),如果還有任務(wù)到來(lái)就會(huì)采取任務(wù)拒絕策略,通常有以下四種策略:

  • ThreadPoolExecutor.AbortPolicy:丟棄任務(wù)并拋出RejectedExecutionException異常。
  • ThreadPoolExecutor.DiscardPolicy:丟棄任務(wù),但是不拋出異常。
  • ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊(duì)列最前面的任務(wù),然后重新提交被拒絕的任務(wù)
  • ThreadPoolExecutor.CallerRunsPolicy:由調(diào)用線程(提交任務(wù)的線程)處理該任務(wù)

線程池的默認(rèn)拒絕策略為AbortPolicy,即丟棄任務(wù)并拋出RejectedExecutionException異常。

4、線程池優(yōu)雅關(guān)閉

從源碼中可以看到,有兩種關(guān)閉方式,shutdown和shutdownNow。

  • executorService.shutdown():線程池拒接收新提交的任務(wù),同時(shí)立馬關(guān)閉線程池,線程池里的任務(wù)不再執(zhí)行。
    public void shutdown() {final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {checkShutdownAccess();//設(shè)置線程池狀態(tài)為SHUTDOWN,之后就不能再向線程池提交任務(wù)了advanceRunState(SHUTDOWN);//遍歷所有未執(zhí)行任務(wù)的線程,對(duì)其設(shè)置中斷interruptIdleWorkers();onShutdown(); // hook for ScheduledThreadPoolExecutor} finally {mainLock.unlock();}//判斷所有任務(wù)是否都已退出,如果退出則設(shè)置標(biāo)記 “TERMINATED”//在這里會(huì)死循環(huán)一直等到所有線程都執(zhí)行完任務(wù)后,再次中斷線程tryTerminate();}private void interruptIdleWorkers(boolean onlyOne) {final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {for (Worker w : workers) {Thread t = w.thread;
//中斷時(shí),先獲取鎖,runWorker中執(zhí)行任務(wù)時(shí),會(huì)先lock加鎖(見(jiàn)上面runWorker源碼)
//所以,這里其實(shí)只會(huì)對(duì)中斷空閑線程if (!t.isInterrupted() && w.tryLock()) {try {t.interrupt();} catch (SecurityException ignore) {} finally {w.unlock();}}}} finally {mainLock.unlock();}}

從上面的源碼中可以看出,當(dāng)我們調(diào)用線程池的shuwdown方法時(shí),如果線程正在執(zhí)行線程池里的任務(wù),即便任務(wù)處于阻塞狀態(tài),線程也不會(huì)被中斷,而是繼續(xù)執(zhí)行(因?yàn)橛屑渔i,所以interruptIdleWorkers中worker獲取不到鎖,所以執(zhí)行不了中斷)。
如果線程池阻塞等待從隊(duì)列里讀取任務(wù)getTask(),則會(huì)被喚醒,但是會(huì)繼續(xù)判斷隊(duì)列是否為空,如果不為空會(huì)繼續(xù)從隊(duì)列里讀取任務(wù),為空則線程退出。

  • executorService.shutdownNow():線程池拒接收新提交的任務(wù),同時(shí)立馬關(guān)閉線程池,線程池里的任務(wù)不再執(zhí)行。
  public List<Runnable> shutdownNow() {List<Runnable> tasks;final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {checkShutdownAccess();
//修改線程池的狀態(tài)為STOP狀態(tài)advanceRunState(STOP);
//遍歷線程池里的所有工作線程,然后調(diào)用線程的interrupt方法interruptWorkers();
//將隊(duì)列里還沒(méi)有執(zhí)行的任務(wù)放到列表里,返回給調(diào)用方tasks = drainQueue();} finally {mainLock.unlock();}tryTerminate();return tasks;}private void interruptWorkers() {final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {for (Worker w : workers)//直接中斷w.interruptIfStarted();} finally {mainLock.unlock();}}private List<Runnable> drainQueue() {BlockingQueue<Runnable> q = workQueue;ArrayList<Runnable> taskList = new ArrayList<Runnable>();q.drainTo(taskList);if (!q.isEmpty()) {for (Runnable r : q.toArray(new Runnable[0])) {
//移除工作隊(duì)列中任務(wù),同時(shí)把其返回給調(diào)用方if (q.remove(r))taskList.add(r);}}return taskList;}

當(dāng)我們調(diào)用線程池的shutdownNow時(shí),如果線程正在getTask方法中執(zhí)行,則會(huì)通過(guò)for循環(huán)進(jìn)入到if語(yǔ)句,于是getTask返回null,從而線程退出(getTask源碼中會(huì)先判斷線程狀態(tài),而上一步已經(jīng)把線程狀態(tài)修改為STOP了)。不管線程池里是否有未完成的任務(wù)。

如果線程因?yàn)閳?zhí)行提交到線程池里的任務(wù)而處于阻塞狀態(tài),則會(huì)導(dǎo)致報(bào)錯(cuò)(如果任務(wù)里沒(méi)有捕獲InterruptedException異常),否則線程會(huì)執(zhí)行完當(dāng)前任務(wù),然后通過(guò)getTask方法返回為null來(lái)退出。

總結(jié):調(diào)用完shutdownNow和shuwdown方法后,并不代表線程池已經(jīng)完成關(guān)閉操作,它只是異步的通知線程池進(jìn)行關(guān)閉處理。如果要同步等待線程池徹底關(guān)閉后才繼續(xù)往下執(zhí)行,需要調(diào)用awaitTermination方法進(jìn)行同步等待。

5、ThreadPoolExecutor參數(shù)設(shè)置

5.1 默認(rèn)值

- corePoolSize=1
- queueCapacity=Integer.MAX_VALUE
- maxPoolSize=Integer.MAX_VALUE
- keepAliveTime=60s
- allowCoreThreadTimeout=false
- rejectedExecutionHandler=AbortPolicy()

5.2 自定義線程池參數(shù)的合理設(shè)置

為了說(shuō)明合理設(shè)置的條件,我們首先確定有以下?個(gè)相關(guān)參數(shù):

  • 1.tasks,程序每秒需要處理的最?任務(wù)數(shù)量(假設(shè)系統(tǒng)每秒任務(wù)數(shù)為100~1000)
  • 2.tasktime,單線程處理?個(gè)任務(wù)所需要的時(shí)間(每個(gè)任務(wù)耗時(shí)0.1秒)
  • 3.responsetime,系統(tǒng)允許任務(wù)最?的響應(yīng)時(shí)間(每個(gè)任務(wù)的響應(yīng)時(shí)間不得超過(guò)2秒)

corePoolSize:核心線程數(shù)

每個(gè)任務(wù)需要tasktime秒處理,則每個(gè)線程每秒可處理1/tasktime個(gè)任務(wù)。系統(tǒng)每秒有tasks個(gè)任務(wù)需要處理,則需要的線程數(shù)為:tasks/(1/tasktime),即tasks*tasktime個(gè)線程數(shù)。
假設(shè)系統(tǒng)每秒任務(wù)數(shù)為100到1000之間,每個(gè)任務(wù)耗時(shí)0.1秒,則需要100x0.1?1000x0.1,即10到100個(gè)線程。

那么corePoolSize應(yīng)該設(shè)置為大于10。具體數(shù)字最好根據(jù)8020原則,即80%情況下系統(tǒng)每秒任務(wù)數(shù),若系統(tǒng)80%的情況下任務(wù)數(shù)小于200,最多時(shí)為1000,則corePoolSize可設(shè)置為20。

queueCapacity:任務(wù)隊(duì)列的長(zhǎng)度:

任務(wù)隊(duì)列的長(zhǎng)度要根據(jù)核心線程數(shù),以及系統(tǒng)對(duì)任務(wù)響應(yīng)時(shí)間的要求有關(guān)。隊(duì)列長(zhǎng)度可以設(shè)置為(corePoolSize/tasktime) * responsetime=(20/0.1) * 2=400,即隊(duì)列長(zhǎng)度可設(shè)置為400。

如果隊(duì)列長(zhǎng)度設(shè)置過(guò)?,會(huì)導(dǎo)致任務(wù)響應(yīng)時(shí)間過(guò)長(zhǎng),如以下寫(xiě)法:
LinkedBlockingQueue queue = new LinkedBlockingQueue();
這實(shí)際上是將隊(duì)列長(zhǎng)度設(shè)置為Integer.MAX_VALUE,將會(huì)導(dǎo)致線程數(shù)量永遠(yuǎn)為corePoolSize,再也不會(huì)增加,當(dāng)任務(wù)數(shù)量陡增時(shí),任務(wù)響應(yīng)時(shí)間也將隨之陡增。

maxPoolSize:最大線程數(shù)

當(dāng)系統(tǒng)負(fù)載達(dá)到最?值時(shí),核心線程數(shù)已無(wú)法按時(shí)處理完所有任務(wù),這時(shí)就需要增加線程。
每秒200個(gè)任務(wù)需要20個(gè)線程,那么當(dāng)每秒達(dá)到1000個(gè)任務(wù)時(shí),則需要(1000-queueCapacity) * 0.1,即60個(gè)線程,可將maxPoolSize設(shè)置為60。

keepAliveTime:

線程數(shù)量只增加不減少也不?。當(dāng)負(fù)載降低時(shí),可減少線程數(shù)量,如果?個(gè)線程空閑時(shí)間達(dá)到keepAliveTiime,該線程就退出。默認(rèn)情況下線程池最少會(huì)保持corePoolSize個(gè)線程。keepAliveTiime設(shè)定值可根據(jù)任務(wù)峰值持續(xù)時(shí)間來(lái)設(shè)定。

rejectedExecutionHandler:

根據(jù)具體情況來(lái)決定,任務(wù)不重要可丟棄,任務(wù)重要?jiǎng)t要利用一些緩沖機(jī)制來(lái)處理

以上關(guān)于線程數(shù)量的計(jì)算并沒(méi)有考慮CPU的情況。若結(jié)合CPU的情況,比如,當(dāng)線程數(shù)量達(dá)到50時(shí),CPU達(dá)到100%,則將maxPoolSize設(shè)置為60也不合適,此時(shí)若系統(tǒng)負(fù)載長(zhǎng)時(shí)間維持在每秒1000個(gè)任務(wù),則超出線程池處理能?,應(yīng)設(shè)法降低每個(gè)任務(wù)的處理時(shí)間(tasktime)。

補(bǔ)充:線程中斷

在程序中,我們是不能隨便中斷一個(gè)線程的,因?yàn)檫@是極其不安全的操作,我們無(wú)法知道這個(gè)線程正運(yùn)行在什么狀態(tài),它可能持有某把鎖,強(qiáng)行中斷可能導(dǎo)致鎖不能釋放的問(wèn)題;或者線程可能在操作數(shù)據(jù)庫(kù),強(qiáng)行中斷導(dǎo)致數(shù)據(jù)不一致混亂的問(wèn)題。正因此,JAVA里將Thread的stop方法設(shè)置為過(guò)時(shí),以禁止大家使用。

一個(gè)線程什么時(shí)候可以退出呢?當(dāng)然只有線程自己才能知道。

所以我們這里要說(shuō)的Thread的interrrupt方法,本質(zhì)不是用來(lái)中斷一個(gè)線程。是將線程設(shè)置一個(gè)中斷狀態(tài)。

當(dāng)我們調(diào)用線程的interrupt方法,它有兩個(gè)作用:

  • 1、如果此線程處于阻塞狀態(tài)(比如調(diào)用了wait方法,io等待),則會(huì)立馬退出阻塞,并拋出InterruptedException異常,線程就可以通過(guò)捕獲InterruptedException來(lái)做一定的處理,然后讓線程退出。
  • 2、如果此線程正處于運(yùn)行之中,則線程不受任何影響,繼續(xù)運(yùn)行,僅僅是線程的中斷標(biāo)記被設(shè)置為true。所以線程要在適當(dāng)?shù)奈恢猛ㄟ^(guò)調(diào)用isInterrupted方法來(lái)查看自己是否被中斷,并做退出操作。

如果線程的interrupt方法先被調(diào)用,然后線程調(diào)用阻塞方法進(jìn)入阻塞狀態(tài),InterruptedException異常依舊會(huì)拋出。
如果線程捕獲InterruptedException異常后,繼續(xù)調(diào)用阻塞方法,將不再觸發(fā)InterruptedException異常。

http://www.risenshineclean.com/news/28591.html

相關(guān)文章:

  • 動(dòng)態(tài)網(wǎng)站編程文明seo
  • 高校網(wǎng)站建設(shè)需求分析報(bào)告百度號(hào)注冊(cè)官網(wǎng)
  • 網(wǎng)站做詞seo服務(wù)是什么意思
  • 做靜態(tài)網(wǎng)站用什么軟件西安網(wǎng)絡(luò)推廣外包公司
  • html php網(wǎng)站開(kāi)發(fā)網(wǎng)址如何被快速收錄
  • 基于bmob的網(wǎng)站開(kāi)發(fā)廣州seo代理
  • 有沒(méi)有專(zhuān)做于投融資的網(wǎng)站互換鏈接的方法
  • 黨中央建設(shè)的少年網(wǎng)站百度流量統(tǒng)計(jì)
  • 網(wǎng)站排名軟件包年找代寫(xiě)文章寫(xiě)手
  • 餐飲網(wǎng)站 設(shè)計(jì)技術(shù)教程優(yōu)化搜索引擎整站
  • 綿陽(yáng)城鄉(xiāng)住房建設(shè)廳網(wǎng)站廣告信息發(fā)布平臺(tái)
  • 做網(wǎng)站的費(fèi)用記哪個(gè)科目百度pc網(wǎng)頁(yè)版登錄入口
  • 怎么建小說(shuō)網(wǎng)站微信crm客戶管理系統(tǒng)
  • 邢臺(tái)網(wǎng)站制作地方谷歌引擎搜索
  • jsp 做網(wǎng)站還是php北京網(wǎng)站制作推廣
  • 鎮(zhèn)江模板網(wǎng)站小紅書(shū)廣告投放平臺(tái)
  • 移動(dòng)網(wǎng)站趨勢(shì)推廣引流平臺(tái)
  • 在線設(shè)計(jì)軟件南寧seo渠道哪家好
  • 做淘寶詳情頁(yè)的素材網(wǎng)站2023年8月疫情爆發(fā)
  • 外貿(mào)網(wǎng)站建設(shè)網(wǎng)站漯河seo公司
  • 自己做的網(wǎng)站 怎么在網(wǎng)上銷(xiāo)售登錄百度app
  • 重慶微信網(wǎng)站制作廈門(mén)人才網(wǎng)唯一官網(wǎng)登錄
  • wordpress全球化移投界seo
  • 網(wǎng)站建設(shè)需準(zhǔn)備什么軟件門(mén)戶網(wǎng)站怎么做
  • wordpress億起發(fā)搜索引擎seo
  • 網(wǎng)站優(yōu)化和推廣方案ppt免費(fèi)網(wǎng)站大全下載
  • 有趣的網(wǎng)站網(wǎng)址之家百度搜索關(guān)鍵詞優(yōu)化方法
  • 自己做網(wǎng)站推廣在那個(gè)網(wǎng)站鄭州做網(wǎng)站最好的公司
  • 侯斯特 wordpressseo軟件服務(wù)
  • 找南昌兼職做網(wǎng)站的百度第三季度財(cái)報(bào)2022