一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 淺析Java線程的中斷機制

淺析Java線程的中斷機制

2021-03-09 14:23傅易 Java教程

本篇文章通過代碼實例給大家分享了學習Java線程的中斷機制的一些心得內容,有興趣的朋友學習下吧。

線程中斷機制提供了一種方法,用于將線程從阻塞等待中喚醒,嘗試打斷目標線程的現有處理流程,使之響應新的命令。Java 留給開發者這一自由,我們應當予以善用。
今天我們聊聊 Java 線程的中斷機制。

線程中斷機制提供了一種方法,有兩種常見用途:

將線程從阻塞等待中喚醒,并作出相應的“受控中斷”處理。
嘗試告知目標線程:請打斷現有處理流程,響應新的命令。
以第一種用途為例,請看以下代碼:

?
1
2
3
4
5
6
7
8
9
synchronized (lock) {
  try {
    while (!check()) {
      lock.wait(1000);
    }
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
}

這段代碼使用了 Java 提供的 wait/notify 機制,線程執行 lock.wait() 會阻塞,有三種情況使線程恢復運行。

1、超時 1000ms 結束,正常執行下一句代碼。

2、另一個線程執行下述代碼主動喚醒

?
1
2
3
synchronized (lock) {
  lock.notifyAll(); // or lock.notify();
}

這也會正常執行下一句代碼。

3、另一個線程要求等待的線程“中斷”

?
1
2
3
// 拿到等待中的線程的引用
Thread a;
a.interrupt();

被“中斷”的線程 a,會在 lock.wait() 處拋出 InterruptedException 異常。

綜上所述,你可以認為 object.wait() 內部在做這些事:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
boolean checkTimeout = timeout > 0;
Thread current = Thread.currentThread();
lock.addWaiter(current);
while (!current.isNotified()) {
  if (current.isInterrupted()) {
    current.clearInterrupted();
    throw new InterruptedException();
  }
  if (checkTimeout) {
    if (timeout == 0) break;
    timeout--;
  }
}

這不完全準確,因為 wait 不使用這種“忙輪詢”的方式做檢查,但關于標志位的判斷邏輯是正確的。

讓我們從上文所述的“手動發出中斷”這一操作開始探究

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// sun.nio.ch.Interruptible
public interface Interruptible {
  void interrupt(Thread var1);
}
// java.lang.Thread
private volatile Interruptible blocker;
private final Object blockerLock = new Object();
public void interrupt() {
  if (this != Thread.currentThread())
    checkAccess();
  synchronized (blockerLock) {
    Interruptible b = blocker;
    if (b != null) {
      interrupt0();
      b.interrupt(this);
      return;
    }
  }
  interrupt0();
}
// Just to set the interrupt flag
private native void interrupt0();

能夠看出,thread.interrupt() 先判斷權限,然后實際調用 interrupt0() 設置線程的中斷標志,如果當前線程有 nio 的 Interruptible 那么還會回調它。

注意,interrupt0() 只是設置了線程的中斷標志。

當一個線程并不阻塞,沒有在 object.wait(), thread.join(), Thread.sleep() 等不受 Java 程序邏輯控制的區域時,那么會發生什么事情?答案是不會發生任何事情,線程是否被打斷只能通過主動地檢查中斷標志得知。

怎么檢查?Thread 暴露了兩個接口,Thread.interrupted() 和 thread.isInterrupted()。

?
1
2
3
4
5
6
7
8
// java.lang.Thread
public static boolean interrupted() {
  return currentThread().isInterrupted(true);
}
public boolean isInterrupted() {
  return isInterrupted(false);
}
private native boolean isInterrupted(boolean clearInterrupted);

能夠看出,兩者都是依靠內部的 isInterrupted(boolean),而它會返回線程是否被打斷,并根據需要清空中斷標志。

當一個函數調用會發生阻塞,Java 庫函數在阻塞的源頭簽名里標記 throws InterruptedException,并要求編寫 try catch 處理中斷。

當線程發生了阻塞,就像上文所述,Java 檢查到中斷標志,先將其清除,然后拋出 InterruptedException。

?
1
2
3
4
5
// java.lang.Object
public final void wait() throws InterruptedException {
  wait(0);
}
public final native void wait(long timeout) throws InterruptedException;

如果一個線程收到 InterruptedException,之后仍然執行了會引發阻塞的代碼,它將像“沒事人”一樣繼續阻塞住。因為 Java 在內部將中斷標志清除了!

我們常見地編寫以下三類處理 InterruptedException 的代碼:

將 InterruptedException 交由上層處理。

?
1
2
3
4
5
public void foo() throws InterruptedException {
  synchronized (lock) {
    lock.wait();
  }
}

遇到 InterruptedException 重設中斷標志位。

?
1
2
3
4
5
6
7
8
try {
  synchronized (lock) {
    lock.wait();
  }
} catch (InterruptedException e) {
  Thread.currentThread().interrupt();
  //break;
}

先忙完,再重新拋出 InterruptedException。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void bar() throws InterruptedException {
  InterruptedException ie = null;
  boolean done = false;
  while (!done) {
    synchronized (lock) {
      try {
        lock.wait();
      } catch (InterruptedException e) {
        ie = e;
        continue;
      }
    }
    done = true;
  }
  if (ie != null) {
    throw ie;
  }
}

如果一個線程無視中斷標志和 InterruptedException,它仍然能夠跑的很好。但這與我們設計多線程的初衷是違背的,我們希望線程之間是和諧的有序協作以實現特定功能,因此受控線程應當對中斷作出響應。而 Java 留給開發者這一自由,我們應當予以善用。

以上就是這次給大家介紹的Java線程的中斷機制相關知識的全部內容,如果還有任何不明白的可以在下方的留言區域討論,感謝對服務器之家的支持。

原文鏈接:https://my.oschina.net/tridays/blog/1587259

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产好深好硬好爽我还要视频 | 无遮挡h肉动漫高清在线 | 欧美日韩高清完整版在线观看免费 | 美女禁区视频免费观看精选 | 日本红怡院亚洲红怡院最新 | 出a级黑粗大硬长爽猛视频 吃胸膜奶视频456 | 欧美视频免费 | 欧美一区精品 | 亚洲高清在线天堂精品 | 久久伊人久久 | 国产清纯91天堂在线观看 | 国产成人欧美 | 亚洲男人天堂a | 日本中文字幕一区二区有码在线 | 亚洲欧美国产另类 | 成年性香蕉漫画在线观看 | 俄罗斯女同和女同xx | 维修工的调教 | 国产成人久久精品一区二区三区 | 天堂网在线.www天堂在线视频 | 花房乱爱在线观看 | 韩国三级年轻的小婊孑 | 国产成人综合亚洲一区 | 女女宿舍互慰h文小说 | 亚洲一区二区日韩欧美gif | 无限资源在线观看完整版免费下载 | 18美女光胸光屁屁洗澡 | 日韩精品1 | 韩国三级在线高速影院 | 欧美极品brazzers 高清 | 暖暖的韩国免费观看 | 无人区乱码1区2区3区网站 | 蜜月aⅴ免费一区二区三区 蜜桃影像传媒推广 | 范冰冰a级一级特级毛片 | 日本特级a禁片在线播放 | 香港日本三级亚洲三级 | 国产午夜亚洲精品理论片不卡 | futa百合高肉全h | 日产乱码卡一卡2卡三卡四福利 | 男人的天堂视频 | 视频久久 |