一、復習上一節內容
- wait()方法、中斷正在運行的執行緒會拋出java.lang.InterruptedException、當執行緒呼叫共享物件的wait()方法時,當前執行緒只會釋放當前共享變數的鎖,不會釋放該執行緒所持有的其他共享變數的鎖,
- wait(long timeout,int nanos)實作、wait(0)內部呼叫了wait()方法、notify()隨機喚醒、notifyAll()全部喚醒、join方法、sleep方法、yield方法,以及sleep與yield方法的區別
二、執行緒中斷interrupt
- 使用interrupt()方法去中斷執行緒,isInterrupted()來檢測這個執行緒是否被中斷了
package com.ruigege.threadFoundation1;
public class SubThreadInterruptedState {
public static void main(String[] args) throws InterruptedException{
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
while(!Thread.currentThread().isInterrupted()) {
System.out.println("子執行緒沒有中斷");
}
System.out.println("子執行緒雖然中斷了,但是并沒有結束");
}
});
thread1.start();
Thread.sleep(5);//保證子執行緒能夠執行起來
thread1.interrupt();//中斷子執行緒,可以理解為時間片這里不給它,一會再給它因此子執行緒會持續運行結束,這函式就是一個表姐而已
System.out.println(thread1.isInterrupted());
thread1.join();
System.out.println("主執行緒結束");
}
}

- 解釋:
- void interrupt()方法的執行可以理解為做一個標記而已,而不是真的去停止了該執行緒,該執行緒還會繼續執行下去直到結束
- boolean isInterrupted()方法是用來檢測該標記的,如果被中斷了,就回傳true;否則回傳false
- static boolean Interruped()方法也是用來檢測該標記的,但是多個一個步驟,就是去除這個印記,一會舉例說明,
public static boolean Interrupted(){
return Thread.currentThread().isInterrupted(true);
}
1.那么呼叫interrupt()方法的時候,會在執行緒的哪里中斷呢?
- 執行緒在呼叫wait()、sleep()、join()方法的時候,如果其他執行緒給與它interrupt方法,那么會在前面那三種方法處中斷
- 我們直接舉個上述的例子,比如執行一個執行緒,讓他中間sleep幾秒鐘,那么此時使用interrupt來打斷,在sleep函式這里拋出一個java.lang.InterruptedException
package com.ruigege.threadFoundation1;
public class InterruptThreadWhenSleeping {
public static void main(String[] args) throws InterruptedException {
Thread threadOne = new Thread(new Runnable() {
@Override
public void run(){
try {
System.out.println("子執行緒開始了,并開始睡眠幾秒");
Thread.sleep(3000);
System.out.println("睡眠結束");
}catch(InterruptedException e) {
e.printStackTrace();
}
}
});
threadOne.start();
Thread.sleep(1000);
threadOne.interrupt();
threadOne.join();
}
}

- 在寫這個例子的時候,我想要使用run() throws InterruptedException,但是編譯不通過,于是改用try...catch...捕捉例外,百度了一下ava run()方法無法throws 例外,其實沒看懂,應該是JVM的原理,還得繼續學啊,
- boolean isInterrupted()和boolean interrupted()兩個方法的區別在于,前一個就是檢測到底中斷標志的,后一個也是檢測中斷標志,但是檢測完之后,會去掉該標志,我們直接舉例
package com.ruigege.threadFoundation1;
public class isInterruptedAndinterrupted {
public static void main(String[] args) throws InterruptedException {
Thread threadOne = new Thread(new Runnable() {
@Override
public void run() {
for(;;) {
}
}
});
threadOne.start();
threadOne.interrupt();
System.out.println("子執行緒isInterrupted:"+threadOne.isInterrupted());
System.out.println("子執行緒Interrupted:"+threadOne.interrupted());
System.out.println("主執行緒Interrupted:"+Thread.interrupted());
System.out.println("子執行緒isInterrupted:"+threadOne.isInterrupted());
threadOne.join();
}
}

- 注意第二個,為什么時false,我們要看原始碼,return Thread.currentThread().isInterrupted(),所以雖然子執行緒物件呼叫,但是這是在主執行緒中運行該陳述句,所以是false
- 下面來在看一個
package com.ruigege.threadFoundation1;
public class SubThreadInvokeTag {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while(!Thread.currentThread().isInterrupted()) {
}
System.out.println("子執行緒isInterruped()狀態:"+Thread.currentThread().isInterrupted());
System.out.println("子執行緒interruped()狀態:"+Thread.currentThread().interrupted());
System.out.println("子執行緒isInterruped()狀態:"+Thread.currentThread().isInterrupted());
}
});
thread.start();
thread.interrupt();
System.out.println("主執行緒isInterrupted狀態"+Thread.currentThread().isInterrupted());
thread.join();
}
}

三、原始碼:
- 所在包:com.ruigege.ThreadFoundation1
https://github.com/ruigege66/ConcurrentJava- CSDN:https://blog.csdn.net/weixin_44630050
- 博客園:https://www.cnblogs.com/ruigege0000/
- 歡迎關注微信公眾號:傅里葉變換,個人賬號,僅用于技術交流

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/196875.html
標籤:Java
下一篇:群暉DS218+部署kafka
