日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

interrupt

發布時間:2024/9/30 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 interrupt 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 在sleep時如果這個線程發生中斷,也只是將堵塞狀態變為非堵塞狀態

package info;import java.util.concurrent.*; public class Factory implements Runnable{public void run() {System.out.println("begin run");while(true) {try {System.out.println("sleeping");Thread.sleep(1000);}catch(InterruptedException e) {System.out.println("catch interrupt");e.printStackTrace();}}}public static void main(String[] args) {Thread t = new Thread(new Factory());t.start();try {Thread.sleep(2000);}catch(InterruptedException e) {System.out.println("main interrupt");}System.out.println("main thread excute t interrupt");t.interrupt();}}
output:

begin run
sleeping
sleeping
main thread excute t interrupt
sleeping
catch interrupt
java.lang.InterruptedException: sleep interruptedsleeping


at java.lang.Thread.sleep(Native Method)
at info.Factory.run(Factory.java:11)
at java.lang.Thread.run(Unknown Source)
sleeping
sleeping
sleeping
sleeping
sleeping
sleeping
sleeping
sleeping
sleeping
sleeping
sleeping
sleeping
sleeping
sleeping
sleeping
sleeping

被catch了,只是將這個線程從堵塞狀態變為非堵塞狀態,并死循環


如果將代碼修改為

public void run() {System.out.println("begin run");while(!Thread.interrupted()) {try {System.out.println("sleeping");Thread.sleep(2000);}catch(InterruptedException e) {System.out.println("catch interrupt");System.out.println("thread is interrupted ? " + Thread.interrupted());e.printStackTrace();}}}
output:

begin run
sleeping
sleeping
main thread excute t interrupt
catch interrupt
thread is interrupted ? false
java.lang.InterruptedException: sleep interruptedsleeping


at java.lang.Thread.sleep(Native Method)
at info.Factory.run(Factory.java:11)
at java.lang.Thread.run(Unknown Source)
sleeping
sleeping
sleeping

還是死循環,雖然發生了中斷,但是interrupted的中斷位還是false,這是因為在拋出異常時候,自動將其設為了false


將代碼修改如下,就可以了

public void run() {System.out.println("begin run");while(!Thread.interrupted()) {try {System.out.println("sleeping");Thread.sleep(2000);}catch(InterruptedException e) {System.out.println("catch interrupt");System.out.println("thread is interrupted ? " + Thread.interrupted());Thread.currentThread().interrupt();e.printStackTrace();}}}

?對于非阻塞中的線程, 只是改變了中斷狀態, 即Thread.Interrupted()將返回true; 對于可取消的阻塞狀態中的線程, 比如等待在這些函數上的線程, Thread.sleep(), Object.wait(), Thread.join(), 這個線程收到中斷信號后, 會拋出InterruptedException, 同時會把中斷狀態置回為false.

public void run() {System.out.println("begin run");while(!Thread.interrupted()) {System.out.println("sleeping");}}

通用的寫法,不論是否是堵塞,應該這樣寫

public void run() {System.out.println("begin run");try {while(!Thread.interrupted()) {System.out.println("sleeping");//如果在這句話,就是非堵塞的時候收到中斷信號,那么其interrupted變為true,在下次循環判斷時就退出Thread.sleep(2000); //如果在這句話,也就是在堵塞的時候收到中斷信號,那么就會拋出一個異常,interrupted在拋出異常時又變為false}}catch(InterruptedException e) {System.out.println("catch interrupt");}}

看到一個例子,可以比較好的展現interrupt的機制

import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock;public class test {/*** @param args*/private ReentrantLock lock = new ReentrantLock();public Runnable createTask() {return new Runnable() {public void run() {while (true) {try {lock.lock();{//if(lock.tryLock()) {//if (lock.tryLock(500, TimeUnit.MILLISECONDS)) {try {System.out.println("locked "+Thread.currentThread().getName());System.out.println("begin sleep "+Thread.currentThread().getName());Thread.sleep(10000);System.out.println("end sleep "+Thread.currentThread().getName());} finally {lock.unlock();System.out.println("unlock "+Thread.currentThread().getName());}break;} // else { // System.out.println("unable to lock "+Thread.currentThread().getName()); // }} catch(InterruptedException e) {System.out.println("interrupted "+Thread.currentThread().getName());}}//while}};}public static void main(String[] args)throws Exception {test t = new test();Thread t1 = new Thread(t.createTask(), "T1");Thread t2 = new Thread(t.createTask(), "T2");t1.start();t2.start();Thread.sleep(600);t2.interrupt();}}
output:

locked T1
begin sleep T1
end sleep T1
unlock T1
locked T2
begin sleep T2
unlock T2
interrupted T2
locked T2
begin sleep T2
end sleep T2
unlock T2


T1線程先得到所,就睡眠了10秒,T2就堵塞了10秒,在這10秒內主線程對T2發出了一個interrupt消息,但是因為T2在等待鎖的過程中,是不會響應中斷信號的。

10秒之后,T2獲得了鎖,注意調用線程interrupt的唯一作用就是將線程內部的interruption變量變為了ture,但是一旦線程進入不是因為等待鎖而導致的堵塞時,發現這個變量是ture, 這時就產生了一個interruption中斷,但是注意這里finally的作用,即使有異常了,但是也得必須運行finally塊內部的代碼,然后再跳到外層的catch中。


如果調用線程的.isInterrupted()函數,就會顯示是否有中斷,然后在把中斷變量設為false.


如果將16行改為lock.lockInterruptibly(); 就是T2在等待鎖的過程中,也會響應中斷信號。


import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock;public class test {/*** @param args*/private ReentrantLock lock = new ReentrantLock();public Runnable createTask() {return new Runnable() {public void run() {while (true) {try {//lock.lockInterruptibly();//{//if(lock.tryLock()) {if (lock.tryLock(5000, TimeUnit.MILLISECONDS)) {try {System.out.println("locked "+Thread.currentThread().getName());System.out.println("begin sleep "+Thread.currentThread().getName());Thread.sleep(10000);System.out.println("end sleep "+Thread.currentThread().getName());} finally {lock.unlock();System.out.println("unlock "+Thread.currentThread().getName());}break;}else {System.out.println("unable to lock "+Thread.currentThread().getName());}} catch(InterruptedException e) {System.out.println("interrupted "+Thread.currentThread().getName());}}//while}};}public static void main(String[] args)throws Exception {test t = new test();Thread t1 = new Thread(t.createTask(), "T1");Thread t2 = new Thread(t.createTask(), "T2");t1.start();Thread.sleep(50);t2.start();Thread.sleep(600);t2.interrupt();}}
tryLock在等待鎖的時候也會響應中斷




看看這個程序有什么問題?

public class SemaphoreTest extends Thread {Semaphore position;private int id;public SemaphoreTest(int i, Semaphore s) {this.id = i;this.position = s;}public void run() {try {if (position.availablePermits() > 0) {System.out.println("顧客[" + id + "]進入廁所,有空位");} else {System.out.println("顧客[" + id + "]進入廁所,沒空位,排隊");}position.acquire(); System.out.println("【" + id + "】acquire坑位");Thread.sleep((int) (Math.random() * 1000));System.out.println("【" + id + "】完畢release");position.release(); }catch (Exception e) {e.printStackTrace();}}public static void main(String args[]) {ExecutorService pool = Executors.newCachedThreadPool();Semaphore position = new Semaphore(2); // 初始化兩個空位for (int i = 0; i < 5; i++) {pool.submit(new SemaphoreTest(i, position));}System.out.println("開始釋放線程池資源");pool.shutdownNow();System.out.println("完成釋放線程池資源");position.acquireUninterruptibly(2); System.out.println("如廁完畢,清理廁所");position.release(2); } }


shutdownNow就是向正在運行的程序發出 interrupt

但是堵塞著的程序并沒有finally塊來釋放semaphore,導致主線程死等



總結

以上是生活随笔為你收集整理的interrupt的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。