摘要:線程狀態(tài)內(nèi)部枚舉類還未可運(yùn)行狀態(tài)運(yùn)行狀態(tài)。無限期等待狀態(tài)。注意,這只是一個(gè),可能無實(shí)質(zhì)影響。線程中斷中斷線程判斷是否被中斷判斷是否被中斷,并清除當(dāng)前中斷狀態(tài)的中斷是一種協(xié)作機(jī)制。僅僅只是將線程的中斷狀態(tài)置為,該中斷狀態(tài)由方法設(shè)置。
Daemon Thread
Java中有兩類線程:User Thread(用戶線程)、Daemon Thread(守護(hù)線程,后臺一些系統(tǒng)性的服務(wù),比如垃圾回收線程、JIT線程)?。
如果 User Thread已經(jīng)全部退出運(yùn)行了,只剩下Daemon Thread存在了,那么虛擬機(jī)也就退出了(不管Daemon Thread是否結(jié)束)。
設(shè)置守護(hù)線程:
Thread?daemonTread?=?new?Thread();?? daemonThread.setDaemon(true);??//必須在thread.start()之前設(shè)置,否則會(huì)跑出一個(gè)IllegalThreadStateException異常。 daemonThread.isDaemon();??//檢驗(yàn)守護(hù)線程。
在Daemon線程中產(chǎn)生的新線程也是Daemon的。?
線程狀態(tài)Thread內(nèi)部枚舉類:
public enum State { NEW, //還未start() RUNNABLE, //(可運(yùn)行狀態(tài)、運(yùn)行狀態(tài)。到底是哪個(gè)狀態(tài)由CPU時(shí)間片輪轉(zhuǎn)來決定,輪到了就是運(yùn)行狀態(tài),沒輪到就是可運(yùn)行狀態(tài)。) BLOCKED, //阻塞狀態(tài)。申請某些鎖或某個(gè)對象的監(jiān)視器,線程會(huì)被阻塞住。 WAITING, //無限期等待狀態(tài)。調(diào)用了wait方法。進(jìn)入Waiting狀態(tài)的線程會(huì)等待其他線程給它notify,通知到之后由Waiting狀態(tài)又切換到Runnable狀態(tài)繼續(xù)執(zhí)行。 TIMED_WAITING, //有限期等待狀態(tài)。等待xx秒還是沒有被notify,則自動(dòng)切換到Runnable狀態(tài)。 TERMINATED; //結(jié)束狀態(tài)。 }
注:在實(shí)例化線程并start()之后,線程是進(jìn)入可運(yùn)行狀態(tài)。
API線程優(yōu)先級:
并不一定是高優(yōu)先級一定先完成。只是高優(yōu)先級完成的概率比較大,但是低優(yōu)先級還是有可能先完成的。
Thread.yield()
Thread.yield()只是對CPU的一個(gè)暗示,暗示當(dāng)前線程可讓出運(yùn)行位置(從運(yùn)行狀態(tài)轉(zhuǎn)到可運(yùn)行狀態(tài)),讓其他線程占用CPU核心。注意,這只是一個(gè)hint,可能無實(shí)質(zhì)影響。也就是說不能保證當(dāng)前運(yùn)行的線程立即轉(zhuǎn)化到可運(yùn)行狀態(tài)。
Thread.join()
Thread t = new Thread(() -> { //do something }); t.start(); t.join(1000); //等待線程t結(jié)束或1000毫秒
join本質(zhì)是Object.wait(long timeout),即當(dāng)前線程(主線程)進(jìn)入waiting狀態(tài),監(jiān)控對象為t。當(dāng)一個(gè)線程運(yùn)行完成終止后,將會(huì)調(diào)用notifyAll方法去喚醒等待在該線程實(shí)例上的所有線程,該操作由JVM完成。
Object.wait(long timeout)
將當(dāng)前線程進(jìn)入waiting狀態(tài)(釋放了鎖),直到調(diào)用Object.notify()或Object.notifyAll() 或時(shí)間超過timeout。
synchronized (MonitorObject) { // do something MonitorObject.wait(); // do something MonitorObject.notifyAll(); }
wait、notify、notifyAll方法必須在同步塊中(正在監(jiān)視對象)。
sleep和wait主要區(qū)別:
sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法。
Object.notify()
Wakes up a single thread that is waiting on this object"s monitor. If any threads are waiting on this object, one of them is chosen to be awakened.
notifyAll()就是喚醒所有線程。
public void Thread.interrupt() // 中斷線程 public boolean Thread.isInterrupted() // 判斷是否被中斷 public static boolean Thread.interrupted() // 判斷是否被中斷,并清除當(dāng)前中斷狀態(tài)
Java的中斷是一種協(xié)作機(jī)制。也就是說Thread.interrupt()并不一定就中斷了正在運(yùn)行的線程,它只是要求線程自己在合適的時(shí)機(jī)中斷自己。
interrupt()僅僅只是將線程的中斷狀態(tài)置為true,該中斷狀態(tài)由native方法interrupt0()設(shè)置。
interrupt()只針對3種情況:
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
If this thread is blocked in an I/O operation upon a java.nio.channels.InterruptibleChannel then the channel will be closed, the thread"s interrupt status will be set, and the thread will receive a java.nio.channels.ClosedByInterruptException.
If this thread is blocked in a java.nio.channels.Selector then the thread"s interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector"s wakeup method were invoked.
對于其他情況,只會(huì)將線程中斷狀態(tài)置為true。
對于非阻塞線程,只是改變了中斷狀態(tài),并不會(huì)使線程停止:
Thread nonBlocking = new Thread(() -> { while (true) { System.out.println("Produce -> ");// do something } }); nonBlocking.start(); nonBlocking.interrupt();// this thread"s interrupt status will be set nonBlocking.join();
你應(yīng)該這樣做:
Thread nonBlocking = new Thread(() -> { while (true) { if (Thread.currentThread().isInterrupted()) { System.out.println("Interrupted!"); break; } System.out.println("Produce -> "); /* do something */ } });
//
nonBlocking.start(); Thread.sleep(10); //確保第一次循環(huán)跑過if判斷 nonBlocking.interrupt(); nonBlocking.join();
對于阻塞線程:
Thread blocking = new Thread(() -> { while (true) { if (Thread.currentThread().isInterrupted()) { System.out.println("Interrupted!"); break; } try { Thread.sleep(60_000); } catch (InterruptedException e) { System.out.println("InterruptedException When blocking"); /*因?yàn)閽伋霎惓:髸?huì)清除中斷狀態(tài),所以設(shè)置中斷狀態(tài),從而使得下一個(gè)while循環(huán)if判斷為true,跳出循環(huán)。*/ Thread.currentThread().interrupt(); } } });
//
blocking.start(); Thread.sleep(10); //確保第一次循環(huán)跑過if判斷 blocking.interrupt(); blocking.join();
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/67268.html
摘要:下面我們通過代碼來看一下實(shí)現(xiàn)和區(qū)別三種實(shí)現(xiàn)繼承,重寫方法實(shí)現(xiàn)接口,實(shí)現(xiàn)方法實(shí)現(xiàn)接口,實(shí)現(xiàn)方法,帶有返回值和異常如何使用第一種實(shí)現(xiàn)方式第二種實(shí)現(xiàn)方式第三種實(shí)現(xiàn)從代碼可以看出以上提到的區(qū)別,,。第二種方式并沒有體現(xiàn)共用同一個(gè)。 Java實(shí)現(xiàn)線程的三種方式和區(qū)別 Java實(shí)現(xiàn)線程的三種方式: 繼承Thread 實(shí)現(xiàn)Runnable接口 實(shí)現(xiàn)Callable接口 區(qū)別: 第一種方式繼承T...
摘要:的應(yīng)用方式代碼塊作用范圍在中,作用對象是調(diào)用這個(gè)代碼塊的對象。方法進(jìn)來了出來了運(yùn)行的結(jié)果如下等把方法執(zhí)行完,釋放了的鎖,才開始執(zhí)行。靜態(tài)方法運(yùn)行的結(jié)果如下等待執(zhí)行完才執(zhí)行,說明是類鎖類所的另外一種形式運(yùn)行結(jié)果如下 synchronized的應(yīng)用方式 代碼塊:作用范圍在{}中,作用對象是調(diào)用這個(gè)代碼塊的對象。 方法:作用范圍是一個(gè)方法,作用對象是調(diào)用這個(gè)方法的對象。 靜態(tài)方法:作用范圍...
摘要:在程序開發(fā)中一定遇到并發(fā)編程的場景雖然我們大部分時(shí)間并不直接使用但是是多線程的基礎(chǔ)面試中也會(huì)總是被問到與線程有關(guān)的問題那么線程都有哪些知識呢最近在研究線程的源碼的時(shí)候也總結(jié)了關(guān)于線程一些基本知識線程是什么線程是輕量級的進(jìn)程是操作系統(tǒng)調(diào)度任務(wù) 在程序開發(fā)中, 一定遇到并發(fā)編程的場景, 雖然我們大部分時(shí)間并不直接使用Thread, 但是Thread是多線程的基礎(chǔ), 面試中也會(huì)總是被問到與線...
摘要:主線程名我們啟動(dòng)的一個(gè)程序可以理解為一個(gè)進(jìn)程一個(gè)進(jìn)程中包含一個(gè)主線程線程可以理解為一個(gè)子任務(wù)中可以通過下面代碼來獲取默認(rèn)的主線程名運(yùn)行結(jié)果為這是線程的名字并不是方法通過此線程來執(zhí)行方法而已兩種方式創(chuàng)建線程繼承類實(shí)現(xiàn)接口實(shí)現(xiàn)接口并且多線程運(yùn)行 Java 主線程名 我們啟動(dòng)的一個(gè)程序可以理解為一個(gè)進(jìn)程, 一個(gè)進(jìn)程中包含一個(gè)主線程, 線程可以理解為一個(gè)子任務(wù). Java 中可以通過下面代碼來...
默認(rèn)使用的線程池 不傳executor時(shí)默認(rèn)使用ForkJoinPool.commonPool() IntStream.range(0, 15).parallel().forEach(i -> { System.out.println(Thread.currentThread()); }); 輸出 Thread[ForkJoinPool.commonPoo...
摘要:本人郵箱歡迎轉(zhuǎn)載轉(zhuǎn)載請注明網(wǎng)址代碼已經(jīng)全部托管有需要的同學(xué)自行下載類學(xué)習(xí)線程的開發(fā)者首先遇到的第一個(gè)類就是通過使用類我們就可以啟動(dòng)停止中斷一個(gè)線程在同一個(gè)時(shí)間片里可能會(huì)有多個(gè)線程在執(zhí)行每個(gè)線程都擁有它自己的方法調(diào)用堆棧參數(shù)和變量每個(gè)至少會(huì)有 本人郵箱: 歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明網(wǎng)址 http://blog.csdn.net/tianshi_kcogithub: https://github...
閱讀 3322·2023-04-25 19:42
閱讀 1340·2021-11-23 10:11
閱讀 2282·2021-11-16 11:51
閱讀 1601·2019-08-30 15:54
閱讀 2048·2019-08-29 18:44
閱讀 1626·2019-08-23 18:24
閱讀 499·2019-08-23 17:52
閱讀 1775·2019-08-23 15:33