成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

java中線程池的生命周期與線程中斷

suxier / 1168人閱讀

摘要:線程中斷線程中斷就是一種協(xié)作機(jī)制。它并不會(huì)真正的中斷一個(gè)正在運(yùn)行的線程,而只是發(fā)出中斷請(qǐng)求,然后由線程在下一個(gè)合適的時(shí)刻中斷自己。

線程池生命周期包括:

RUNNING:接收新的任務(wù)并處理隊(duì)列中的任務(wù)

SHUTDOWN:不接收新的任務(wù),但是處理隊(duì)列中的任務(wù)

STOP:不接收新的任務(wù),不處理隊(duì)列中的任務(wù),同時(shí)中斷處理中的任務(wù)

TIDYING:所有的任務(wù)處理完成,有效的線程數(shù)是0

TERMINATED:terminated()方法執(zhí)行完畢

轉(zhuǎn)換成TIDYING狀態(tài)的線程會(huì)運(yùn)行terminated方法。執(zhí)行完terminated()方法之后,所有等待在awaitTermination()就會(huì)返回。

轉(zhuǎn)換過程為:

線程池是空的即有效線程數(shù)是0
取消

如果代碼能夠在某個(gè)操作正常完全之前置入“完成”狀態(tài),那么這個(gè)操作就稱為可取消的。java中提供了協(xié)作式機(jī)制,使請(qǐng)求取消的任務(wù)和代碼遵循一種協(xié)商好的協(xié)議。

線程中斷

線程中斷就是一種協(xié)作機(jī)制。它并不會(huì)真正的中斷一個(gè)正在運(yùn)行的線程,而只是發(fā)出中斷請(qǐng)求,然后由線程在下一個(gè)合適的時(shí)刻中斷自己。
Thread中的中斷方法包括

interrupt
public void interrupt() {
    if (this != Thread.currentThread())
        checkAccess();//非當(dāng)前線程有可能拋出SecurityException

    synchronized (blockerLock) {
        //用于執(zhí)行可終端的IO操作對(duì)應(yīng)的方法
        Interruptible b = blocker;
        if (b != null) {
            //僅設(shè)置終端標(biāo)記
            interrupt0(); 
            //執(zhí)行實(shí)現(xiàn)了Interruptible接口的防范
            b.interrupt(this);
            return;
        }
    }
    //僅設(shè)置終端標(biāo)記
    interrupt0();
}

調(diào)用它根據(jù)線程的不同場(chǎng)景,有不同的結(jié)果

如果線程阻塞的是一個(gè)可以中斷的channel,那么channel會(huì)被關(guān)閉,同時(shí)線程會(huì)收到j(luò)ava.nio.channels.ClosedByInterruptException,并且會(huì)設(shè)置中斷標(biāo)志

//AbstractInterruptibleChannel中:
protected final void begin() {
        if (interruptor == null) {
            interruptor = new Interruptible() {
                    public void interrupt(Thread target) {
                        synchronized (closeLock) {
                            if (!open)
                                return;
                            open = false;
                            interrupted = target;
                            try {
                            //關(guān)閉channel
                            AbstractInterruptibleChannel.this.implCloseChannel();
                            } catch (IOException x) { }
                        }
                    }};
        }
        blockedOn(interruptor);
        Thread me = Thread.currentThread();
        if (me.isInterrupted())
            interruptor.interrupt(me);
    }

如果線程阻塞在Selector,執(zhí)行它的 wakeup方法,因而selector會(huì)立即返回,同時(shí)會(huì)設(shè)置中斷標(biāo)志

//AbstractSelector中:
protected final void begin() {
    if (interruptor == null) {
        interruptor = new Interruptible() {
                public void interrupt(Thread ignore) {
                    //執(zhí)行wakeup,Selector立即返回
                    AbstractSelector.this.wakeup();
                }};
    }
    AbstractInterruptibleChannel.blockedOn(interruptor);
    Thread me = Thread.currentThread();
    if (me.isInterrupted())
        interruptor.interrupt(me);
}

如果線程阻塞在wait/join/sleep,線程的中斷標(biāo)志會(huì)被清除,并拋出InterruptedException

非上述三種情況,僅設(shè)置中斷標(biāo)志

可以看出調(diào)用interrupt并不意味著立即停止目標(biāo)線程正在進(jìn)行的工作,而只是傳遞了請(qǐng)求中斷的消息

interrupted

清除當(dāng)前線程的中斷狀態(tài),并返回之前的值。它實(shí)際執(zhí)行的就是當(dāng)前線程的isInterrupted(true)

public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}
假設(shè)當(dāng)前線程是中斷的,此時(shí)調(diào)用會(huì)返回true,如果在下次調(diào)用之前沒有中斷,此時(shí)調(diào)用會(huì)返回false
isInterrupted

返回目標(biāo)線程的中斷狀態(tài),只有線程狀態(tài)是中斷才會(huì)返回true,其它時(shí)候返回false

public boolean isInterrupted() {
    return isInterrupted(false);
}

可以看到interrupted和isInterrupted 調(diào)用的都是isInterrupted方法,只不過參數(shù)不一樣。它的參數(shù)實(shí)際代表的是是否要清除中斷標(biāo)記,為true也就清除,在java中的定義如下

private native boolean isInterrupted(boolean ClearInterrupted);
參考linux上的實(shí)現(xiàn)為
```
bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
    "possibility of dangling Thread pointer");

  OSThread* osthread = thread->osthread();

  bool interrupted = osthread->interrupted();

  if (interrupted && clear_interrupted) {
    osthread->set_interrupted(false); //如果中斷了,并且要清除中斷標(biāo)記,就改變終端標(biāo)記
    // consider thread->_SleepEvent->reset() ... optional optimization
  }

  return interrupted;
}
```
響應(yīng)中斷 - 處理InterruptedException

一般策略如下

傳遞異常,使當(dāng)前方法也成為可中斷的

恢復(fù)中斷狀態(tài),使得調(diào)用棧中的上層代碼能夠?qū)ζ溥M(jìn)行處理

處理不可中斷的阻塞

并非所有的可阻塞方法或者阻塞機(jī)制都能響應(yīng)中斷,停止線程的方法類似于中斷

Java.io中的Socket I/O。InputStream和OutputStream中的read和write等不會(huì)響應(yīng)中斷,可以關(guān)閉底層的套接字拋出SocketException

Java.io中的同步I/O。大多數(shù)的標(biāo)準(zhǔn)的channel都實(shí)現(xiàn)了InterruptibleChannel,它內(nèi)部一般都是拋出ClosedByInterruptException,并關(guān)閉鏈路

Selector的異步I/O。阻塞在了Selector.select,通過調(diào)用wakeup或者close來提前返回。

獲取某個(gè)鎖。由于線程等待某個(gè)內(nèi)置鎖,它會(huì)認(rèn)為自己能等到,所以不會(huì)處理中斷,通過Lock的lockInterruptibly可以同時(shí)實(shí)現(xiàn)等待鎖并且響應(yīng)中斷

Thread.stop本身是不安全的。停止一個(gè)線程會(huì)釋放它所有的鎖的監(jiān)視器,如果有任何一個(gè)受這些監(jiān)視器保護(hù)的對(duì)象出現(xiàn)了狀態(tài)不一致,其它的線程也會(huì)以不一致的狀態(tài)查看這個(gè)對(duì)象,其它線程在這個(gè)對(duì)象上的任何操作都是無法預(yù)料的
為什么廢棄了Thread.stop
關(guān)閉

應(yīng)用程序準(zhǔn)備退出時(shí),這些服務(wù)所擁有的線程也應(yīng)該結(jié)束。
ExecutorService提供了兩種方法:shutdown和shutdownNow

shutdown在執(zhí)行完隊(duì)列中的所有任務(wù)之后,才關(guān)閉,它并不會(huì)接收新的任務(wù)

shutdownNow則是立馬關(guān)閉正在執(zhí)行的任務(wù),并返回還沒有開始的任務(wù)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/72392.html

相關(guān)文章

  • Java并發(fā)總結(jié)

    摘要:限期阻塞調(diào)用方法等待時(shí)間結(jié)束或線程執(zhí)行完畢。終止?fàn)顟B(tài)線程執(zhí)行完畢或出現(xiàn)異常退了。和都會(huì)檢查線程何時(shí)中斷,并且在發(fā)現(xiàn)中斷時(shí)提前放回。工廠方法將線程池的最大大小設(shè)置為,而將基本大小設(shè)置為,并將超時(shí)大小設(shè)置為分鐘。 wait()、notify()、notifyAll() Object是所有類的基類,它有5個(gè)方法組成了等待、通知機(jī)制的核心:notify()、notifyAll()、wait()...

    szysky 評(píng)論0 收藏0
  • [Java并發(fā)-7]java線程小節(jié)

    摘要:在領(lǐng)域,實(shí)現(xiàn)并發(fā)程序的主要手段就是多線程??蛇\(yùn)行狀態(tài)指的是線程可以分配執(zhí)行。當(dāng)?shù)却氖录霈F(xiàn)了,線程就會(huì)從休眠狀態(tài)轉(zhuǎn)換到可運(yùn)行狀態(tài)。導(dǎo)出線程棧,分析線程狀態(tài)是診斷并發(fā)問題的一個(gè)重要工具。 在 Java 領(lǐng)域,實(shí)現(xiàn)并發(fā)程序的主要手段就是多線程。線程是操作系統(tǒng)里的一個(gè)概念,雖然各種不同的開發(fā)語言如 Java、C# 等都對(duì)其進(jìn)行了封裝,但原理和思路都是相同都。Java 語言里的線程本質(zhì)上就是...

    Sunxb 評(píng)論0 收藏0
  • 手撕ThreadPoolExecutor線程池源碼

    摘要:所以,在時(shí)執(zhí)行也是為了保證線程池在狀態(tài)下必須要有一個(gè)線程來執(zhí)行任務(wù)。 這篇文章對(duì)ThreadPoolExecutor創(chuàng)建的線程池如何操作線程的生命周期通過源碼的方式進(jìn)行詳細(xì)解析。通過對(duì)execute方法、addWorker方法、Worker類、runWorker方法、getTask方法、processWorkerExit從源碼角度詳細(xì)闡述,文末有彩蛋。 exexcte方法 public...

    Corwien 評(píng)論0 收藏0
  • Java 并發(fā)學(xué)習(xí)筆記

    摘要:方法可以將當(dāng)前線程放入等待集合中,并釋放當(dāng)前線程持有的鎖。此后,該線程不會(huì)接收到的調(diào)度,并進(jìn)入休眠狀態(tài)。該線程會(huì)喚醒,并嘗試恢復(fù)之前的狀態(tài)。 并發(fā) 最近重新復(fù)習(xí)了一邊并發(fā)的知識(shí),發(fā)現(xiàn)自己之前對(duì)于并發(fā)的了解只是皮毛。這里總結(jié)以下Java并發(fā)需要掌握的點(diǎn)。 使用并發(fā)的一個(gè)重要原因是提高執(zhí)行效率。由于I/O等情況阻塞,單個(gè)任務(wù)并不能充分利用CPU時(shí)間。所以在單處理器的機(jī)器上也應(yīng)該使用并發(fā)。為...

    DrizzleX 評(píng)論0 收藏0
  • Java線程池從使用到閱讀源碼(3/10)

    摘要:最后,我們會(huì)通過對(duì)源代碼的剖析深入了解線程池的運(yùn)行過程和具體設(shè)計(jì),真正達(dá)到知其然而知其所以然的水平。創(chuàng)建線程池既然線程池是一個(gè)類,那么最直接的使用方法一定是一個(gè)類的對(duì)象,例如。單線程線程池單線程線程 我們一般不會(huì)選擇直接使用線程類Thread進(jìn)行多線程編程,而是使用更方便的線程池來進(jìn)行任務(wù)的調(diào)度和管理。線程池就像共享單車,我們只要在我們有需要的時(shí)候去獲取就可以了。甚至可以說線程池更棒,...

    468122151 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<