<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
使用interrupt來通知,而不是強制
java提供了interrrupt讓一個執行緒來通知另一個執行緒停止
如果想中斷一個執行緒,但是那個執行緒不想去中斷,那就無能為力,我們沒有強制去中斷執行緒的手段,因為執行緒停止前需要做一定的收尾工作
所以正確停止執行緒,是如何用interrupt來通知那個執行緒,以及被停止的執行緒如何進行配合
程式碼展示
public class stopThreadWithoutSleep implements Runnable{ public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new stopThreadWithoutSleep()); thread.start(); Thread.sleep(1000); thread.interrupt(); } @Override public void run() { int num = 0; while(num <= Integer.MAX_VALUE / 2) { if (num % 10000 == 0) { System.out.println(num + "是10000的倍數"); } num++; } System.out.println("結束"); } } /* 由於太長,只展示結尾部分的結果 1073710000是10000的倍數 1073720000是10000的倍數 1073730000是10000的倍數 1073740000是10000的倍數 結束 * */
public class stopThreadWithoutSleep implements Runnable{ public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new stopThreadWithoutSleep()); thread.start(); Thread.sleep(1000); thread.interrupt(); } @Override public void run() { int num = 0; while(!Thread.currentThread().isInterrupted() && num <= Integer.MAX_VALUE / 2) { if (num % 10000 == 0) { System.out.println(num + "是10000的倍數"); } num++; } System.out.println("結束"); } } /* 由於太長,只展示結尾部分的結果 587830000是10000的倍數 587840000是10000的倍數 587850000是10000的倍數 587860000是10000的倍數 結束 * */
程式碼展示
public class stopThreadWithSleep { public static void main(String[] args) { Runnable runnable = () -> { int num = 0; while (num <= 300 && !Thread.currentThread().isInterrupted()) { if (num % 100 == 0) { System.out.println(num + "是100的倍數"); } num++; } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }; Thread thread = new Thread(runnable); thread.start(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } thread.interrupt(); } } /* * 0是100的倍數 100是100的倍數 200是100的倍數 300是100的倍數 java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.jx.JavaTest.stopThread.stopThreadWithSleep.lambda$main$0(stopThreadWithSleep.java:15) at java.lang.Thread.run(Thread.java:748) * */
public class stopThreadWithSleepEveryLoop { public static void main(String[] args) { Runnable runnable = () -> { int num = 0; try { while (num <= 10000) { if (num % 100 == 0) { System.out.println(num + "是100的倍數"); } num++; Thread.sleep(10); } } catch (InterruptedException e) { e.printStackTrace(); } }; Thread thread = new Thread(runnable); thread.start(); try { Thread.sleep(5000); } catch ( InterruptedException e) { e.printStackTrace(); } thread.interrupt(); } } /* * 0是100的倍數 100是100的倍數 200是100的倍數 300是100的倍數 java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.jx.JavaTest.stopThread.stopThreadWithSleepEveryLoop.lambda$main$0(stopThreadWithSleepEveryLoop.java:15) at java.lang.Thread.run(Thread.java:748) Process finished with exit code 0 * * */
當catch寫到while內,則不能正常中斷
public class CantInterrupt { public static void main(String[] args) { Runnable runnable = () -> { int num = 0; while (num <= 10000) { if (num % 100 == 0) { System.out.println(num + "是100的倍數"); } num ++; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } }; Thread thread = new Thread(runnable); thread.start(); try { Thread.sleep(5000); } catch ( InterruptedException e) { e.printStackTrace(); } thread.interrupt(); } } /* * 0是100的倍數 100是100的倍數 200是100的倍數 300是100的倍數 java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.jx.JavaTest.stopThread.CantInterrupt.lambda$main$0(CantInterrupt.java:14) at java.lang.Thread.run(Thread.java:748) 400是100的倍數 500是100的倍數 600是100的倍數 700是100的倍數 800是100的倍數 900是100的倍數 Process finished with exit code -1 * */
public class CantInterrupt { public static void main(String[] args) { Runnable runnable = () -> { int num = 0; while (num <= 10000 && !Thread.currentThread().isInterrupted()) { if (num % 100 == 0) { System.out.println(num + "是100的倍數"); } num++; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } }; Thread thread = new Thread(runnable); thread.start(); try { Thread.sleep(5000); } catch ( InterruptedException e) { e.printStackTrace(); } thread.interrupt(); } } /* 0是100的倍數 100是100的倍數 200是100的倍數 300是100的倍數 java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.jx.JavaTest.stopThread.CantInterrupt.lambda$main$0(CantInterrupt.java:14) at java.lang.Thread.run(Thread.java:748) 400是100的倍數 500是100的倍數 Process finished with exit code -1 * */
public class StopThreadInProd implements Runnable{ public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new StopThreadInProd()); thread.start(); Thread.sleep(1000); thread.interrupt(); } @Override public void run() { while (true) { System.out.println("start"); try { throwInMethod(); } catch (InterruptedException e) { System.out.println("儲存紀錄檔/關閉程式"); e.printStackTrace(); } } } private void throwInMethod() throws InterruptedException { Thread.sleep(2000); } } /* * start 儲存紀錄檔/關閉程式 start java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.jx.JavaTest.stopThread.StopThreadInProd.throwInMethod(StopThreadInProd.java:26) at com.jx.JavaTest.stopThread.StopThreadInProd.run(StopThreadInProd.java:17) at java.lang.Thread.run(Thread.java:748) start start Process finished with exit code -1 * * */
public class StopThreadInProd2 implements Runnable{ public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new StopThreadInProd2()); thread.start(); Thread.sleep(1000); thread.interrupt(); } @Override public void run() { while (true) { if (Thread.currentThread().isInterrupted()) { System.out.println("Interrupt"); break; } reInterrupt(); } } private void reInterrupt() { try { Thread.sleep(2000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); e.printStackTrace(); } } } /* java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.jx.JavaTest.stopThread.StopThreadInProd2.reInterrupt(StopThreadInProd2.java:25) at com.jx.JavaTest.stopThread.StopThreadInProd2.run(StopThreadInProd2.java:19) at java.lang.Thread.run(Thread.java:748) Interrupt * * */
public class StopThreadInProd2 implements Runnable{ public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new StopThreadInProd2()); thread.start(); Thread.sleep(1000); thread.interrupt(); } @Override public void run() { while (true) { if (Thread.currentThread().isInterrupted()) { System.out.println("Interrupt"); break; } reInterrupt(); } } private void reInterrupt() { try { Thread.sleep(2000); } catch (InterruptedException e) { // Thread.currentThread().interrupt(); e.printStackTrace(); } } } /* java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.jx.JavaTest.stopThread.StopThreadInProd2.reInterrupt(StopThreadInProd2.java:25) at com.jx.JavaTest.stopThread.StopThreadInProd2.run(StopThreadInProd2.java:19) at java.lang.Thread.run(Thread.java:748) * * */
public class StopThread implements Runnable{ @Override public void run() { // 模擬指揮軍隊,一共五個連隊,每個連隊一百人 // 以連隊為單位發放武器 for (int i = 0; i < 5; i++) { System.out.println("連隊" + i + "領取武器"); for (int j = 0; j < 10; j++) { System.out.println(j); try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("連隊" + i + "領取完畢"); } } public static void main(String[] args) { Thread thread = new Thread(new StopThread()); thread.start(); try { thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } thread.stop(); } } /* * 連隊0領取武器 0 1 2 3 4 5 6 7 8 9 連隊0領取完畢 連隊1領取武器 0 1 2 3 4 5 Process finished with exit code 0 * */
public class Volatile implements Runnable { private volatile boolean canceled = false; @Override public void run() { int num = 0; try { while (num <= 10000 && !canceled) { if (num % 100 == 0) { System.out.println(num + " 是100的倍數"); } num++; Thread.sleep(1); } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { Volatile v = new Volatile(); Thread thread = new Thread(v); thread.start(); Thread.sleep(1000); v.canceled = true; } } /* *0 是100的倍數 100 是100的倍數 200 是100的倍數 300 是100的倍數 400 是100的倍數 500 是100的倍數 600 是100的倍數 Process finished with exit code 0 * * */
// 模擬生產者和消費者 public class cantStop { public static void main(String[] args) throws InterruptedException { // 阻塞佇列 // 滿了之後,放不進去 // 空的時候取資料,也會堵塞 ArrayBlockingQueue storage = new ArrayBlockingQueue(10); Producer producer = new Producer(storage); Thread producerThread = new Thread(producer); producerThread.start(); Thread.sleep(1000); Consumer consumer = new Consumer(storage); while (consumer.needMore()) { System.out.println(consumer.storage.take() + "被消費"); Thread.sleep(100); } System.out.println("消費者不需要更多資料"); // 消費者不需要資料,讓生產者停下來 producer.canceled = true; } } // 生產者 class Producer implements Runnable { public volatile boolean canceled = false; BlockingQueue storage; public Producer(BlockingQueue storage) { this.storage = storage; } @Override public void run() { int num = 0; try { while (num <= 10000 && !canceled) { if (num % 100 == 0) { // 當堵塞佇列滿了之後,會堵塞在這裡,而這段程式碼沒有判斷機制 storage.put(num); System.out.println("num" + "生產"); } num++; } } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println("生產者停止執行"); } } } // 消費者 class Consumer { BlockingQueue storage; public Consumer(BlockingQueue storage) { this.storage = storage; } public boolean needMore() { if (Math.random() > 0.9) { return false; } return true; } } /* * num生產 num生產 num生產 num生產 num生產 num生產 num生產 num生產 num生產 num生產 0被消費 num生產 消費者不需要更多資料 * * */
public class finxed { public static void main(String[] args) throws InterruptedException { finxed finxed = new finxed(); // 阻塞佇列 // 滿了之後,放不進去 // 空的時候取資料,也會堵塞 ArrayBlockingQueue storage = new ArrayBlockingQueue(10); Producer producer = finxed.new Producer(storage); Thread producerThread = new Thread(producer); producerThread.start(); Thread.sleep(1000); Consumer consumer = finxed.new Consumer(storage); while (consumer.needMore()) { System.out.println(consumer.storage.take() + "被消費"); Thread.sleep(100); } System.out.println("消費者不需要更多資料"); // 消費者不需要資料,讓生產者停下來 producerThread.interrupt(); } class Producer implements Runnable { public volatile boolean canceled = false; BlockingQueue storage; public Producer(BlockingQueue storage) { this.storage = storage; } @Override public void run() { int num = 0; try { while (num <= 10000 && !Thread.currentThread().isInterrupted()) { if (num % 100 == 0) { storage.put(num); System.out.println("num" + "生產"); } num++; } } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println("生產者停止執行"); } } } class Consumer { BlockingQueue storage; public Consumer(BlockingQueue storage) { this.storage = storage; } public boolean needMore() { if (Math.random() > 0.9) { return false; } return true; } } } /* * 2100被消費 num生產 2200被消費 num生產 2300被消費 num生產 消費者不需要更多資料 生產者停止執行 java.lang.InterruptedException at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(AbstractQueuedSynchronizer.java:2014) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2048) at java.util.concurrent.ArrayBlockingQueue.put(ArrayBlockingQueue.java:353) at com.jx.JavaTest.stopThread.volatiledmo.finxed$Producer.run(finxed.java:51) at java.lang.Thread.run(Thread.java:748) Process finished with exit code 0 * * */
public void interrupt() { if (this != Thread.currentThread()) checkAccess(); synchronized (blockerLock) { Interruptible b = blocker; if (b != null) { interrupt0(); // Just to set the interrupt flag b.interrupt(this); return; } } interrupt0(); } private native void interrupt0();
public class InterruptedTest { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new Runnable() { @Override public void run() { while (true) { } } }); thread.start(); thread.interrupt(); // 獲取中斷標誌 System.out.println(thread.isInterrupted()); // true // 獲取中斷標誌並重置 System.out.println(thread.interrupted()); //false System.out.println(Thread.interrupted()); // false System.out.println(thread.isInterrupted()); //true thread.join(); System.out.println("over"); } }
到此這篇關於Java執行緒的停止實現原理詳解的文章就介紹到這了,更多相關Java執行緒的停止內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45