国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

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

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

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

Java 線程池的使用,是面試必問的。下面我們來從使用到源碼整理一下。

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

  • 通過Executors來構(gòu)造線程池
1、構(gòu)造一個固定線程數(shù)目的線程池,配置的corePoolSize與maximumPoolSize大小相同,
同時使用了一個無界LinkedBlockingQueue存放阻塞任務(wù),因此多余的任務(wù)將存在阻塞隊(duì)列,
不會由RejectedExecutionHandler處理 
public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}2、構(gòu)造一個緩沖功能的線程池,配置corePoolSize=0,maximumPoolSize=Integer.MAX_VALUE,
keepAliveTime=60s,以及一個無容量的阻塞隊(duì)列 SynchronousQueue,因此任務(wù)提交之后,
將會創(chuàng)建新的線程執(zhí)行;線程空閑超過60s將會銷毀 public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}3、構(gòu)造一個只支持一個線程的線程池,配置corePoolSize=maximumPoolSize=1,
無界阻塞隊(duì)列LinkedBlockingQueue;保證任務(wù)由一個線程串行執(zhí)行 public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));}4、構(gòu)造有定時/延時功能的線程池,配置corePoolSize,無界延遲阻塞隊(duì)列DelayedWorkQueue;
有意思的是:maximumPoolSize=Integer.MAX_VALUE,由于DelayedWorkQueue是無界隊(duì)列,
所以這個值是沒有意義的
對于一些不能及時處理,需要延時處理的操作,用ScheduledExecutorService處理很方便,
比如我們在某些條件下需要清理redis/mysql中數(shù)據(jù)時,但是可能當(dāng)前有些地方還需要用到(并發(fā)),這時用ScheduledExecutorService處理非常合適,
雖然也可以用定時任務(wù)處理,但是定時任務(wù)會一直執(zhí)行,而這里的場景是滿足一定條件去執(zhí)行,而執(zhí)行的機(jī)會又很少。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ì)列是空的時,從隊(duì)列中獲取元素的操作將會被阻塞,
或者當(dāng)隊(duì)列是滿時,往隊(duì)列里添加元素的操作會被阻塞。
試圖從空的阻塞隊(duì)列中獲取元素的線程將會被阻塞,直到其他的線程往空的隊(duì)列插入新的元素。
同樣,試圖往已滿的阻塞隊(duì)列中添加新元素的線程同樣也會被阻塞,直到其他的線程使隊(duì)列重新變得空閑起來,
如從隊(duì)列中移除一個或者多個元素,或者完全清空隊(duì)列.
  • 通過ThreadPoolExecutor自定義線程池
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,  long keepAliveTime,TimeUnit unit,  BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,  RejectedExecutionHandler handler )
* corePoolSize 核心線程池大小----1
* maximumPoolSize 最大線程池大小----3
* keepAliveTime 線程池中超過corePoolSize數(shù)目的空閑線程最大存活時間----30
* keepAliveTime時間單位----TimeUnit.MINUTES 
* workQueue 阻塞隊(duì)列----new ArrayBlockingQueue<Runnable>(5)----阻塞隊(duì)列的容量是5
* threadFactory 新建線程工廠----new CustomThreadFactory()----定制的線程工廠 
* rejectedExecutionHandler 當(dāng)提交任務(wù)數(shù)超過maxmumPoolSize+workQueue之和(3+5),即當(dāng)提交第9個任務(wù)時(前面線程都沒有執(zhí)行完,此測試方法中用 sleep(30), 任務(wù)會交給RejectedExecutionHandler來處理 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ù)時,如果隊(duì)列已滿,那么阻塞指定時間等待隊(duì)列可用,
//等待期間如果被中斷,那么拋出InterruptedException。// 如果插入成功,那么返回true,如果在達(dá)到指定時間后仍然隊(duì)列不可用,
//那么返回false。===========超時退出// 使用put 時,插入數(shù)據(jù)時,如果隊(duì)列已滿,那么阻塞等待隊(duì)列可用,等待期間如果被中斷,
//那么拋出InterruptedException。 =============  一直阻塞:System.out.println("拒絕任務(wù)");executor.getQueue().offer(r); //會有任務(wù)線程不執(zhí)行//executor.getQueue().put(r); //不會有任務(wù)線程不執(zhí)行} catch (Exception e) {e.printStackTrace();}}}// 測試構(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 + "個任務(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.銷毀----此處不能銷毀,因?yàn)槿蝿?wù)沒有提交執(zhí)行完,如果銷毀線程池,任務(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ì)列;如果能加入,說明隊(duì)列沒滿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);}

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

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

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

簡單的說,

  • 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個線程;

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) {//啟動線程,執(zhí)行任務(wù),這里調(diào)用的其實(shí)是worker的run方法,見下面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()時,
//最終執(zhí)行的是Worker類的run方法Worker(Runnable firstTask) {setState(-1); // inhibit interrupts until runWorkerthis.firstTask = firstTask;this.thread = getThreadFactory().newThread(this);}//執(zhí)行任務(wù)時,最后調(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時,task肯定不為空,當(dāng)firstTask執(zhí)行完以后,while循環(huán)等待,//指導(dǎo)從隊(duì)列中獲取到task,即getTask()不為空時,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時,如果還有任務(wù)到來就會采取任務(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ù),同時立馬關(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ù)的線程,對其設(shè)置中斷interruptIdleWorkers();onShutdown(); // hook for ScheduledThreadPoolExecutor} finally {mainLock.unlock();}//判斷所有任務(wù)是否都已退出,如果退出則設(shè)置標(biāo)記 “TERMINATED”//在這里會死循環(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;
//中斷時,先獲取鎖,runWorker中執(zhí)行任務(wù)時,會先lock加鎖(見上面runWorker源碼)
//所以,這里其實(shí)只會對中斷空閑線程if (!t.isInterrupted() && w.tryLock()) {try {t.interrupt();} catch (SecurityException ignore) {} finally {w.unlock();}}}} finally {mainLock.unlock();}}

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

  • executorService.shutdownNow():線程池拒接收新提交的任務(wù),同時立馬關(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ì)列里還沒有執(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ù),同時把其返回給調(diào)用方if (q.remove(r))taskList.add(r);}}return taskList;}

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

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

總結(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è)置

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

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

corePoolSize:核心線程數(shù)

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

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

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

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

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

maxPoolSize:最大線程數(shù)

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

keepAliveTime:

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

rejectedExecutionHandler:

根據(jù)具體情況來決定,任務(wù)不重要可丟棄,任務(wù)重要則要利用一些緩沖機(jī)制來處理

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

補(bǔ)充:線程中斷

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

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

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

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

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

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

http://aloenet.com.cn/news/28591.html

相關(guān)文章:

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