java多線程

java多線程

[TOC]

創(chuàng)建線程

class MyRunnable implements Runnable{
  public void run(){
    //線程執(zhí)行代碼
  }
}
Runnable r = new MyRunnable();
//創(chuàng)建線程并啟動(dòng)
Thread t = new Thread(r);
t.start();

直接調(diào)用Thread類或Runnable類的run方法并不會(huì) 創(chuàng)建線程馏锡,只會(huì)在本線程內(nèi)執(zhí)行

中斷線程

  • 當(dāng)線程的run方法執(zhí)行完畢后或者出現(xiàn)了沒(méi)有捕獲的異常時(shí),線程將終止为严。
  • 當(dāng)對(duì)一個(gè)線程調(diào)用interrupt方法時(shí)痢畜,線程中的中斷標(biāo)志將被置位垛膝,這是每個(gè)線程都有的boolean標(biāo)志,每個(gè)線程都應(yīng)不時(shí)檢查這個(gè)標(biāo)志丁稀,已判斷線程是否中斷吼拥。
  • 使用Thread.currentThread()方法獲取當(dāng)前線程,Thread.currentThread().isInterrupted方法返回當(dāng)前線程被置位的狀態(tài)线衫。但是當(dāng)線程被阻塞(sleep或wait)時(shí)將無(wú)法檢測(cè)中斷狀態(tài)凿可,當(dāng)對(duì)阻塞狀態(tài)的線程調(diào)用interrupt方法時(shí)線程會(huì)拋出interrupted Exception異常。
  • interrupted測(cè)試當(dāng)前線程是否中斷授账,執(zhí)行方法會(huì)將線程的中斷狀態(tài)置為false枯跑。

線程狀態(tài)

  • New(新創(chuàng)建)
  • Runnable(可運(yùn)行)
  • Blocked(被阻塞)
  • Waiting(等待)
  • Timed Waiting(計(jì)時(shí)等待)
  • Terminated(被終止)
  1. 新創(chuàng)建線程

    使用new操作剛剛創(chuàng)建的線程,此時(shí)線程還未開(kāi)始運(yùn)行白热。****

  2. 可運(yùn)行線程

    一旦調(diào)用了Thread的start方法線程就處于runable狀態(tài)敛助,一個(gè)可運(yùn)行的線程可能正在運(yùn)行也可能沒(méi)有運(yùn)行,取決于操作系統(tǒng)的上下文切換屋确。一旦一個(gè)線程開(kāi)始運(yùn)行纳击,可能隨時(shí)被中斷续扔,目的是為了讓其他線程獲得運(yùn)行機(jī)會(huì),操作系統(tǒng)搶占式調(diào)度系統(tǒng)給每一個(gè)可運(yùn)行線程一個(gè)時(shí)間片來(lái)執(zhí)行任務(wù)焕数,時(shí)間片用完時(shí)纱昧,系統(tǒng)剝奪線程的運(yùn)行權(quán),并給其他線程運(yùn)行機(jī)會(huì)堡赔。

  3. 被阻塞或等待的線程

    當(dāng)線程處于被阻塞或等待狀態(tài)時(shí)砌些,它暫時(shí)不活動(dòng),不運(yùn)行任何代碼切消耗資源加匈,直到線程調(diào)度器重新激活它。

    • 當(dāng)一個(gè)線程試圖獲取一個(gè)內(nèi)部對(duì)象鎖仑荐,而該鎖被其他線程持有雕拼,則該線程進(jìn)入阻塞狀態(tài)。當(dāng)其他線程釋放鎖粘招,并且調(diào)度去允許本線程持有時(shí)啥寇,該線程恢復(fù)為非阻塞狀態(tài)。
    • 當(dāng)線程等待另一個(gè)線程通知調(diào)度器一個(gè)條件時(shí)洒扎,它自己進(jìn)入等待狀態(tài)辑甜。
    • Thread.sleep、Object.wait袍冷、Thread.join磷醋、Lock.tryLock、Condition.await方法將線程進(jìn)入等待狀態(tài)胡诗。

    當(dāng)一個(gè)線程被阻塞或等待時(shí)邓线,另一個(gè)線程被調(diào)度為可運(yùn)行狀態(tài),當(dāng)一個(gè)線程重新被激活時(shí)煌恢,調(diào)度器檢查是否比當(dāng)前運(yùn)行線程具有更高優(yōu)先級(jí)骇陈,如果優(yōu)先級(jí)更高則從當(dāng)前運(yùn)行線程中選一個(gè)剝奪當(dāng)前線程優(yōu)先級(jí),選擇一個(gè)新的線程運(yùn)行。

  4. 線程有倆種原因被終止:

    • run方法正常退出而自然死亡瑰抵。
    • 因?yàn)闆](méi)有捕獲的異常終止運(yùn)行而意外死亡你雌。

線程屬性

線程優(yōu)先級(jí)

  • 每一個(gè)線程有一個(gè)優(yōu)先級(jí),默認(rèn)情況二汛,一個(gè)線程繼承它的父線程的優(yōu)先級(jí)婿崭,可以用setPriority方法提高或降低任何一個(gè)線程的優(yōu)先級(jí)∠捌叮可以將優(yōu)先級(jí)設(shè)置為在MIN_PRIORITY(1) 至MAX_PRIORITY(10)之間逛球,NORM_PRIORITY=5。
  • 線程優(yōu)先級(jí)高度依賴于操作系統(tǒng)調(diào)度苫昌,java優(yōu)先級(jí)被映射到操作系統(tǒng)的優(yōu)先級(jí)颤绕。優(yōu)先個(gè)數(shù)也許更多幸海,也許更少。在linux上線程優(yōu)先級(jí)被忽略奥务,所有線程具有相同優(yōu)先級(jí)物独。

守護(hù)線程

可以通過(guò)調(diào)用t.setDaemon(true);將線程轉(zhuǎn)換為守護(hù)線程。守護(hù)線程的唯一用途就是為其他線程提供服務(wù)氯葬。當(dāng)只剩下守護(hù)線城時(shí)虛擬機(jī)就退出了挡篓,因?yàn)闆](méi)必要繼續(xù)運(yùn)行程序了。

未捕獲異常處理器

  • 線程的run方法不能拋出任何被檢測(cè)的異常帚称,不被檢測(cè)的異常將導(dǎo)致線程終止官研。但是不需要任何catch子句來(lái)處理可以被傳播的異常,相反在線程死亡前異常被傳遞到一個(gè)用于未捕獲異常的處理器闯睹。該處理器必須屬于一個(gè)實(shí)現(xiàn)Thread.UncaughtExceptionHandler接口的類戏羽。這個(gè)接口只有一個(gè)方法:
void uncaughtException(Thread t,Throwable e)
  • 可以用setUncaughtExceptionHandler方法為任何線程安裝一個(gè)處理器。也可以用Thread類的靜態(tài)方法setDefaultUncaughtExceptionHandler為所有線程安裝一個(gè)默認(rèn)處理器楼吃,替換處理器可以使用日志API發(fā)送未捕獲異常的報(bào)告到日志文件始花。

  • 默認(rèn)處理器為空,但是如果不為獨(dú)立的線程安裝處理器孩锡,此時(shí)的處理器就是該線程的ThreadGroup對(duì)象酷宵。

    線程組(ThreadGroup)是一個(gè)可以統(tǒng)一管理的線程集合。默認(rèn)情況所有線程屬于相同的線程組躬窜,但是也可以建立其他的組浇垦,現(xiàn)在引入了更好的特性用于線程集合的操作,不建議在自己的程序中使用線程組斩披。

  • ThreadGroup類實(shí)現(xiàn)了Thread.UncaughtExceptionHandler接口溜族,它的uncaughtException方法做如下操作:

    1. 如果該線程組有父線程組,那么父線程組的uncaughtException方法被調(diào)用垦沉。
    2. 否則如果Thread.getDefaultExceptionHandler方法返回一個(gè)非空的處理器煌抒,則調(diào)用該處理器。
    3. 否則如果Throwable是ThreadDeath的一個(gè)實(shí)例厕倍,什么都不做寡壮。
    4. 否則,線程的名字以及Throwable的棧蹤跡被輸出讹弯。

同步

鎖對(duì)象

如果使用鎖就不能使用帶資源的try語(yǔ)句况既。

  • 有兩種機(jī)制防止代碼塊受并發(fā)訪問(wèn)的干擾,java提供一個(gè)synchronized關(guān)鍵字達(dá)到這個(gè)目的组民,jdk1.5引入了ReentrantLock類棒仍,用于顯式鎖定。
//ReentrantLock顯式鎖定
myLock.lock();
try{
  
}finally{
  myLock.unlock();
}
  • 當(dāng)一個(gè)對(duì)象有自己的ReentrantLock對(duì)象時(shí)臭胜,如果倆個(gè)線程試圖訪問(wèn)同一個(gè)對(duì)象莫其,那么將觸發(fā)鎖機(jī)制癞尚,如果倆個(gè)線程訪問(wèn)倆個(gè)不同的對(duì)象則都不會(huì)發(fā)生阻塞。

可重入鎖

  • synchronized和ReentrantLock都是可重入鎖乱陡,比如一個(gè)方法是synchronized浇揩,遞歸調(diào)用自己,第一個(gè)獲得鎖后第二次依然可以獲得鎖憨颠,在鎖的內(nèi)部對(duì)象有一個(gè)計(jì)數(shù)器用來(lái)跟蹤鎖的數(shù)量胳徽,unlock或synchronized方法執(zhí)行完畢后對(duì)計(jì)數(shù)器-1。
public class Widget {
    public synchronized void doSomething() {
        ...
    }
}
     
public class LoggingWidget extends Widget {
    public synchronized void doSomething() {
        System.out.println(toString() + ": calling doSomething");
        super.doSomething();//若內(nèi)置鎖是不可重入的爽彤,則發(fā)生死鎖
    }
}
//當(dāng)執(zhí)行子類方法時(shí)养盗,先獲取了一次Widget的鎖,在執(zhí)行super的時(shí)候适篙,又要獲取一次如果是爪瓜,如果不可重入線程就會(huì)死亡。
  • 為每個(gè)鎖關(guān)聯(lián)一個(gè)獲取計(jì)數(shù)器和一個(gè)所有者線程,當(dāng)計(jì)數(shù)值為0的時(shí)候,這個(gè)所就沒(méi)有被任何線程只有.當(dāng)線程請(qǐng)求一個(gè)未被持有的鎖時(shí),JVM將記下鎖的持有者,并且將獲取計(jì)數(shù)值置為1,如果同一個(gè)線程再次獲取這個(gè)鎖,技術(shù)值將遞增,退出一次同步代碼塊,計(jì)算值遞減,當(dāng)計(jì)數(shù)值為0時(shí),這個(gè)鎖就被釋放.

條件對(duì)象

  • 一個(gè)鎖對(duì)象可以有一個(gè)或多個(gè)相關(guān)的條件對(duì)象匙瘪,可以使用newCondition方法獲得一個(gè)條件對(duì)象。

    例如:private Condition sufficientFunds;

  • 如果條件對(duì)象發(fā)現(xiàn)條件不滿足時(shí)蝶缀,它調(diào)用await方法丹喻,當(dāng)前線程現(xiàn)在被阻塞了,并放棄了鎖翁都。等待或者鎖的線程和調(diào)用await方法的線程存在本質(zhì)上的不同碍论,一個(gè)線程調(diào)用await方式,它進(jìn)入該條件的等待集柄慰。當(dāng)鎖可用時(shí)鳍悠,該線程不能馬上解除阻塞。相反坐搔,它處于阻塞狀態(tài)藏研,直到另一個(gè)線程調(diào)用同一條件上的signalAll方法為止。

    當(dāng)另一個(gè)線程轉(zhuǎn)賬時(shí)概行,它應(yīng)該調(diào)用sufficientFunds.signalAll();

    這一調(diào)用重新激活因?yàn)檫@一條件而等待的所有線程蠢挡,當(dāng)這些線程從等待集中移出時(shí),它們?cè)俅纬蔀榭蛇\(yùn)行的凳忙,調(diào)度器將再次激活它們业踏。同時(shí)它們?cè)噲D重新進(jìn)入該對(duì)象,一旦鎖成為可用的涧卵,它們中的某個(gè)將從await調(diào)用返回勤家,獲得該鎖并從被阻塞的地方繼續(xù)執(zhí)行。此時(shí)應(yīng)該重新檢測(cè)條件對(duì)象柳恐,由于無(wú)法確保該條件被滿足伐脖,signalAll方法僅僅是通知正在等待的線程:此時(shí)有可能已經(jīng)滿足條件热幔,值得再去檢測(cè)該條件。

  • 至關(guān)重要的是最終需要某個(gè)線程調(diào)用signalAll方法晓殊,當(dāng)一個(gè)線程調(diào)用await時(shí)断凶,它沒(méi)有辦法重新激活自身,只能靠其他線程來(lái)重新激活巫俺,否則將陷入死鎖狀態(tài)中认烁。

  • 另一個(gè)方法signal則是隨機(jī)解除等待集中某個(gè)線程的阻塞狀態(tài),這比解除所有線程阻塞更加有效介汹,但是隨機(jī)選擇的線程如果發(fā)現(xiàn)仍然不能運(yùn)行却嗡,那么它再次被阻塞,如果沒(méi)有其他線程再次調(diào)用signal嘹承,系統(tǒng)就死鎖了窗价。

while(account[from] < amount){
    condition.await();
}

synchronized 關(guān)鍵字

  • 鎖用來(lái)保護(hù)代碼片段,任何時(shí)刻只能有一個(gè)線程執(zhí)行被保護(hù)的代碼叹卷。
  • 鎖可以管理試圖進(jìn)入被保護(hù)代碼段的線程撼港。
  • 鎖可以擁有一個(gè)或多個(gè)相關(guān)的條件對(duì)象
  • 每個(gè)條件對(duì)象管理那些已經(jīng)進(jìn)入被保護(hù)的代碼段但還不能運(yùn)行的線程。
  1. java中每一個(gè)對(duì)象都有一個(gè)內(nèi)部鎖骤竹,如果一個(gè)方法用synchronized關(guān)鍵字聲明帝牡,那么對(duì)象鎖就保護(hù)整個(gè)方法。
  2. 內(nèi)部對(duì)象鎖只有一個(gè)相關(guān)條件蒙揣,wait方法添加一個(gè)線程到等待集中靶溜,notifyALL/notify方法解除等待線程的阻塞狀態(tài)。等價(jià)于await與signalAll懒震。
class Bank{
    private double[] accounts;
    public synchronized void transfer(int from,int to,int amount) throws InterruptedException{
        while(accounts[from] < amount){//條件
            wait();//如果條件不滿足會(huì)將當(dāng)前線程添加到等待集中
            accounts[from]  -= amount;
            account[to] += amount;
            notifyAll();//轉(zhuǎn)賬完成后通知其他等待中的線程可以檢查條件了
        }
    }
}
  1. 如果Bank類有一個(gè)靜態(tài)同步方法猜谚,那么當(dāng)該方法被調(diào)用時(shí)闹究,Bank.class對(duì)象會(huì)被鎖住,因此沒(méi)有其他線程可以調(diào)用同一個(gè)類的這個(gè)或任何其他的同步靜態(tài)方法。

內(nèi)部鎖和條件的局限性

  • 不能中斷一個(gè)正在試圖獲得鎖的線程铸敏。
  • 試圖獲得鎖時(shí)不能設(shè)定超時(shí)祟霍。
  • 每個(gè)鎖僅有單一的條件新思,可能是不夠的姜性。
  • 最好既不適用lock/Condition也不適用synchronized,許多情況下可以用java.util.concurrent包中的一種機(jī)制恐锣。

監(jiān)視器概念

  • 監(jiān)視器是只包含私有域的類茅主。
  • 每個(gè)監(jiān)視器類的對(duì)象有一個(gè)相關(guān)鎖。
  • 使用該鎖對(duì)所有的方法進(jìn)行加鎖土榴。
  • 該鎖可以有任意多個(gè)相關(guān)條件诀姚。
  • java中每一個(gè)對(duì)象有一個(gè)內(nèi)部鎖和內(nèi)部的條件。
  • 如果一個(gè)方法用synchronized聲明玷禽,表現(xiàn)的就像是一個(gè)監(jiān)視器方法赫段,通過(guò)調(diào)用wait/notifyAll/notify來(lái)訪問(wèn)條件變量呀打。

Volatile域

Volatile關(guān)鍵字為實(shí)例域的同步訪問(wèn)提供了一種免鎖機(jī)制。如果聲明一個(gè)域?yàn)関olatile糯笙,那么編譯器和虛擬機(jī)就知道該域是可能被另一個(gè)線程并發(fā)更新的贬丛。

volatile變量不能提供原子性,例如:public void flipDone(){ done = !done },不能確保翻轉(zhuǎn)域中的值给涕。

線程局部變量

使用ThreadLocal輔助類為各個(gè)線程提供各自的實(shí)例豺憔。

鎖測(cè)試與超時(shí)

  • tryLock方法嘗試獲取鎖,成功后返回true够庙,否則返回false恭应,而且線程可以立刻離開(kāi),同時(shí)可以為tryLock設(shè)置超時(shí)參數(shù)耘眨。
  • 在等待一個(gè)條件時(shí)也可以提供一個(gè)超時(shí): condition.await(100,TimeUnit.MILLISECONDS),如果一個(gè)線程被另一個(gè)線程通過(guò)調(diào)用signalAll或signal激活昼榛,或者已超時(shí),或者線程被中斷剔难,await方法將返回胆屿。

讀寫(xiě)鎖

  1. ReentrantLock 通用鎖,讀寫(xiě)都阻塞偶宫。
  2. ReentrantReadWriteLock 讀寫(xiě)鎖
private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private Lock readLock = rwl.readLock();
private Lock writeLock = rwl.writeLock();

阻塞隊(duì)列

  • 當(dāng)試圖向隊(duì)列添加元素而隊(duì)列已滿莺掠,或是香蔥隊(duì)列移出元素而隊(duì)列為空的時(shí)候,阻塞隊(duì)列導(dǎo)致線程阻塞读宙。
  • 工作者線程可以周期性地將結(jié)果存儲(chǔ)在阻塞隊(duì)列中,其他工作者線程移出中間結(jié)果處理楔绞,隊(duì)列會(huì)自動(dòng)地平衡負(fù)載结闸,如果第一個(gè)線程集運(yùn)行的比第二個(gè)慢,第二個(gè)線程集在等待結(jié)果時(shí)會(huì)阻塞酒朵,如果第一個(gè)線程集運(yùn)行的快桦锄,他將等待第二個(gè)隊(duì)列集趕上來(lái)。

阻塞隊(duì)列方法

方法 正常動(dòng)作 特殊情況動(dòng)作
add 添加元素 隊(duì)列滿拋出IllegalStateException
element 返回頭元素 隊(duì)列空拋出NoSuchElementException
offer 添加元素返回true 隊(duì)列滿了返回false
peed 返回隊(duì)列頭元素 隊(duì)列空返回null
poll 移出并返回頭元素 隊(duì)列空返回null
put 添加一個(gè)元素 隊(duì)列滿則阻塞
remove 移出并返回頭元素 隊(duì)列空拋出NoSuchElementException
take 移出并返回頭元素 如果隊(duì)列空則阻塞

java.util.concurrent包提供了阻塞隊(duì)列的幾個(gè)變種:

  • ArrayBlockingQueue(int capacity,boolean fair) 帶有容量和公平性設(shè)置的阻塞隊(duì)列蔫耽,用循環(huán)數(shù)組實(shí)現(xiàn)结耀。
  • LinkedBlockingQueue 單項(xiàng)鏈表隊(duì)列
  • LinkedBlockingDeque,容量沒(méi)有上邊界匙铡,但可指定最大容量图甜,并有可選參數(shù)指定是否需要公平性,若設(shè)置了公平性鳖眼,則等待時(shí)間最長(zhǎng)的線程會(huì)有限處理黑毅,公平性會(huì)降低性能。
  • PriorityBlockingQueue<E>钦讳,優(yōu)先級(jí)隊(duì)列矿瘦,而不是先進(jìn)先出枕面,元素會(huì)按照優(yōu)先級(jí)順序移出,該隊(duì)列沒(méi)有容量上限缚去,但是如果隊(duì)列是空的取元素操作會(huì)阻塞潮秘,堆實(shí)現(xiàn)。
  • LinkedTransferQueue類實(shí)現(xiàn)了TransferQueue接口易结,允許生產(chǎn)者線程等待枕荞,直到消費(fèi)者準(zhǔn)備就緒可以接受一個(gè)元素,如果生產(chǎn)者調(diào)用qtransfer(item); 這個(gè)調(diào)用會(huì)阻塞衬衬,直到另一個(gè)線程將元素刪除买猖。
  • delayQueue 包含delayed元素?zé)o邊界有阻塞時(shí)間隊(duì)列,只有那些延遲已經(jīng)超過(guò)時(shí)間的元素可以從隊(duì)列中移出滋尉。
  • blockingQueue<E> 普通阻塞隊(duì)列
  • BlockingDeque<E> 雙向阻塞隊(duì)列

線程安全的集合

java.util.concurrent包提供了映射表玉控、有序集合和隊(duì)列的高效實(shí)現(xiàn):ConcurrentHashMap、ConcurrentSkipListMap狮惜、ConcurrentSkipListSet和ConcurrentLinkedQueue高诺。

與大多數(shù)集合不同,size方法不必在常量時(shí)間內(nèi)操作碾篡。確定這樣的集合當(dāng)前的大小通常需要遍歷虱而。

集合返回弱一致性的迭代器。這意味著迭代器不一定能反映出被構(gòu)造之后的所有的修改开泽,但是它們不會(huì)將一個(gè)值返回倆次牡拇。

普通集合如果在迭代器構(gòu)造之后發(fā)生改變,java.util包中的迭代器將拋出一個(gè)ConcurrentModificationException穆律。

  • ConcurrentLinkedQueue<E> 線程安全無(wú)邊界非阻塞隊(duì)列惠呼。
  • ConcurrentSkipListSet<E> 線程安全有序集合。
  • ConcurrentHashMap
  • ConcurrentSkipListMap 線程安全的hash table峦耘。具有類似redis setnx這種方法剔蹋。

Callable與Future

Runnable:沒(méi)有參數(shù)沒(méi)有返回值。

Callable:有參數(shù)有返回值辅髓,只有一個(gè)方法call泣崩。

Future:保存異步計(jì)算的結(jié)果,可以啟動(dòng)一個(gè)計(jì)算洛口,將Future對(duì)象交給某個(gè)線程矫付,然后忘掉它,F(xiàn)uture對(duì)象的持有者在結(jié)果計(jì)算好之后就可以獲得它第焰。

如果運(yùn)行該計(jì)算的線程被中斷技即,get與get帶有超時(shí)的方法都將拋出InterruptedException。

Future的方法:

方法名 描述
V get() 調(diào)用被阻塞直到返回結(jié)果
V get(long timeouot,TimeUnit unit) 阻塞調(diào)用直到超時(shí),超時(shí)拋出InterruptedException
boolean isDone() 是否完成
boolean isCancelled() 是否取消
void cancel(boolean mayInterrupt) 取消而叼,如果還沒(méi)有開(kāi)始將不再開(kāi)始身笤。

FutureTask包裝器可以Callable轉(zhuǎn)換成Future和Runnable,它同時(shí)實(shí)現(xiàn)二者的接口葵陵。

執(zhí)行器

構(gòu)建一個(gè)新的線程是有一定代價(jià)的液荸,如果程序中創(chuàng)建大量臨時(shí)線程,應(yīng)該使用線程池脱篙,一個(gè)線程池包含許多準(zhǔn)備運(yùn)行的空閑線程娇钱,將Runnable對(duì)象交給線程池,就會(huì)有一個(gè)線程調(diào)用run方法绊困。當(dāng)run方法退出時(shí)文搂,線程不會(huì)死亡,二十在池中準(zhǔn)備為下一個(gè)請(qǐng)求提供服務(wù)秤朗。

執(zhí)行器類有許多靜態(tài)工廠方法用來(lái)構(gòu)建線程池

  • newCachedThreadPool:必要時(shí)創(chuàng)建新線程煤蹭;空閑線程只會(huì)被保留60秒。對(duì)于每個(gè)任務(wù)取视,如果有空閑線程可用立即執(zhí)行任務(wù)硝皂,如果沒(méi)有則創(chuàng)建一個(gè)線程。
  • newFixedThreadPool:該池包含固定數(shù)量的線程作谭;空閑線程會(huì)一直被保留稽物。如果任務(wù)數(shù)超過(guò)線程數(shù),將任務(wù)放到隊(duì)列中折欠。
  • newSingleThreadExecutor:只有一個(gè)線程的“池”贝或,該線程順序執(zhí)行每一個(gè)提交的任務(wù)。
  • newScheduledThreadPool:用于預(yù)定執(zhí)行而構(gòu)建的固定線程池锐秦,替代java.util.Timer
  • newSingleThreadScheduledExecutor:用于預(yù)定執(zhí)行而構(gòu)建的單線程“池”

線程池

使用submit方法將Runnable對(duì)象或Callable對(duì)象提交給線程池咪奖。

添加任務(wù)至線程池

Future<?> submit(Runnable task),返回結(jié)果Future<?>可以調(diào)用isDone农猬、cancel、isCancelled方法售淡,但是get方法在完成的時(shí)候只是簡(jiǎn)單地返回null斤葱。

Furure<T> submit(Runnable task,T result) get方法在完成的時(shí)候返回result對(duì)象。

Future<T> submit(Callable<T> task) 返回的Future對(duì)象將在計(jì)算結(jié)果準(zhǔn)備好的時(shí)候得到它揖闸。

線程池會(huì)在方便的時(shí)候今早執(zhí)行提交的任務(wù)揍堕,submit方法會(huì)返回一個(gè)Future對(duì)象,可用來(lái)查詢?cè)撊蝿?wù)狀態(tài)汤纸。

關(guān)閉線程池

當(dāng)用完一個(gè)線程池的時(shí)候調(diào)用shutdown衩茸,該方法啟動(dòng)該池的關(guān)閉序列,被關(guān)閉的線程池不在接受新的任務(wù)贮泞,所有任務(wù)都完成后楞慈,線程池中的線程死亡幔烛。

或者調(diào)用shutdownNow,取消尚未開(kāi)始的任務(wù)囊蓝,并中斷正在運(yùn)行的線程饿悬。

獲取線程池線程數(shù)量

必須將pool對(duì)象強(qiáng)制轉(zhuǎn)換為T(mén)hreadPoolExecutor類對(duì)象,調(diào)用getLargestPoolSize方法聚霜。

預(yù)定執(zhí)行

ScheduledExecutorService接口具有為預(yù)定執(zhí)行或重復(fù)執(zhí)行任務(wù)而設(shè)計(jì)的方法狡恬,可以預(yù)定Runnablehuocallable在初始的延遲之后只運(yùn)行一次,也可以預(yù)定一個(gè)Runnable對(duì)象周期性地運(yùn)行蝎宇。

控制任務(wù)組

invokeAny方法提交所有對(duì)象到一個(gè)Callable對(duì)象的集合中弟劲,并返回某個(gè)已經(jīng)完成了的任務(wù)的結(jié)果。無(wú)法找到返回的究竟是哪個(gè)任務(wù)的結(jié)果姥芥。當(dāng)其中一個(gè)任務(wù)完成時(shí)兔乞,運(yùn)行流程就停止了。

invokeAll方法提交所有對(duì)象到一個(gè)Callable對(duì)象的集合中撇眯,并返回一個(gè)Future對(duì)象的列表报嵌,包含所有任務(wù)的返回結(jié)果。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末熊榛,一起剝皮案震驚了整個(gè)濱河市锚国,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌玄坦,老刑警劉巖血筑,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異煎楣,居然都是意外死亡豺总,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)择懂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)喻喳,“玉大人,你說(shuō)我怎么就攤上這事困曙”砺祝” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵慷丽,是天一觀的道長(zhǎng)蹦哼。 經(jīng)常有香客問(wèn)我,道長(zhǎng)要糊,這世上最難降的妖魔是什么纲熏? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上局劲,老公的妹妹穿的比我還像新娘勺拣。我一直安慰自己,他們只是感情好容握,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布宣脉。 她就那樣靜靜地躺著,像睡著了一般剔氏。 火紅的嫁衣襯著肌膚如雪塑猖。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,578評(píng)論 1 305
  • 那天谈跛,我揣著相機(jī)與錄音羊苟,去河邊找鬼。 笑死感憾,一個(gè)胖子當(dāng)著我的面吹牛蜡励,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播阻桅,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼凉倚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了嫂沉?” 一聲冷哼從身側(cè)響起稽寒,我...
    開(kāi)封第一講書(shū)人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎趟章,沒(méi)想到半個(gè)月后杏糙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蚓土,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年宏侍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜀漆。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谅河,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出确丢,到底是詐尸還是另有隱情绷耍,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布蠕嫁,位于F島的核電站锨天,受9級(jí)特大地震影響毯盈,放射性物質(zhì)發(fā)生泄漏剃毒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赘阀。 院中可真熱鬧益缠,春花似錦、人聲如沸基公。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)轰豆。三九已至胰伍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間酸休,已是汗流浹背骂租。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留斑司,地道東北人渗饮。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像宿刮,于是被迫代替她去往敵國(guó)和親互站。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容