欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java并發(fā)編程 interrupt()方法示例詳解

 更新時(shí)間:2023年06月09日 16:13:19   作者:k3ruanren  
interrrupt()方法可以用來打斷正在運(yùn)行的線程,也可以打斷sleep()、wait()、join()情況下的線程,但是這些情況下被打斷線程的打斷標(biāo)記不同,這篇文章主要介紹了Java并發(fā)編程 interrupt()方法示例詳解,需要的朋友可以參考下

interrupt()用法

打斷正常運(yùn)行的線程

interrrupt()方法可以用來打斷正在運(yùn)行的線程,也可以打斷sleep()、wait()、join()情況下的線程,但是這些情況下被打斷線程的打斷標(biāo)記不同。

import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@Slf4j
public class InterruptTest {
    public static void main(String[] args) throws InterruptedException {
        //創(chuàng)建一個(gè)線程
        Thread t1 = new Thread(() -> {
            //讓線程一直死循環(huán)運(yùn)行
            log.debug("t1開始運(yùn)行.....");
            while(true){
            }
        },"t1");
        //啟動(dòng)線程t1
        t1.start();
        //main主線程一秒后進(jìn)行打斷操作
        TimeUnit.MILLISECONDS.sleep(1000);
        log.debug("interrupt.....");
        t1.interrupt();
    }
}

通過控制臺(tái),可以很清晰的看到,main主線程在執(zhí)行完打斷操作后,t1線程并未終止運(yùn)行,而是繼續(xù)執(zhí)行:

但是如果我們查看線程t1的打斷標(biāo)記會(huì)發(fā)現(xiàn),t1線程的打斷標(biāo)記確實(shí)為true:

Boolean interrupted = Thread.currentThread().isInterrupted();

這是因?yàn)閙ain主線程執(zhí)行interrupt打斷操作,只是通知t1線程,我現(xiàn)在要打斷你,但是具體的執(zhí)行操作還得看t1線程,即t1線程收到main主線程的打斷通知后,由t1線程自己覺得是繼續(xù)運(yùn)行還是被打斷,從而讓出cpu,這樣的好處在于線程t1如果在執(zhí)行某些很重要的任務(wù),突然被其他線程強(qiáng)制打斷可能會(huì)造成很嚴(yán)重的后果,這時(shí)可以讓t1線程自己選擇是否停止工作,也可以在停止工作之前做一些料理后事的工作 。

import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@Slf4j
public class InterruptTest {
    public static void main(String[] args) throws InterruptedException {
        //創(chuàng)建一個(gè)線程
        Thread t1 = new Thread(() -> {
            //讓線程一直死循環(huán)運(yùn)行
            log.debug("t1開始運(yùn)行.....");
            while(true){
                Boolean interrupted = Thread.currentThread().isInterrupted();
                //選擇被打斷后的執(zhí)行操作
                if(interrupted){
                    log.debug("被打斷,停止運(yùn)行...");
                    break;
                }
            }
        },"t1");
        //啟動(dòng)線程t1
        t1.start();
        //main主線程一秒后進(jìn)行打斷操作
        TimeUnit.MILLISECONDS.sleep(1000);
        log.debug("interrupt.....");
        t1.interrupt();
    }
}

14:41:02.906 [t1] DEBUG InterruptTest - t1開始運(yùn)行.....
14:41:03.908 [main] DEBUG InterruptTest - interrupt.....
14:41:03.908 [t1] DEBUG InterruptTest - 被打斷,停止運(yùn)行...

打斷sleep狀態(tài)的線程

import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@Slf4j
public class InterruptTest {
    public static void main(String[] args) throws InterruptedException {
        //創(chuàng)建一個(gè)線程
        Thread t1 = new Thread(() -> {
            //讓線程一直死循環(huán)運(yùn)行
            log.debug("t1開始運(yùn)行.....");
            //t1線程休眠3秒
            try {
                log.debug("t1 is sleeping...");
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        },"t1");
        //啟動(dòng)線程t1
        t1.start();
        //main主線程一秒后進(jìn)行打斷操作
        TimeUnit.MILLISECONDS.sleep(1000);
        log.debug("interrupt.....");
        t1.interrupt();
        //查看t1線程的打斷標(biāo)記
        Boolean interrupted = t1.isInterrupted();
        log.debug(interrupted.toString());
    }

打斷sleep狀態(tài)的線程,會(huì)拋出InterruptedException異常,并且打斷標(biāo)記是false而不是true:

14:50:25.532 [t1] DEBUG InterruptTest - t1開始運(yùn)行.....
14:50:25.536 [t1] DEBUG InterruptTest - t1 is sleeping...
14:50:26.533 [main] DEBUG InterruptTest - interrupt.....
14:50:26.544 [main] DEBUG InterruptTest - false
Exception in thread "t1" java.lang.RuntimeException: java.lang.InterruptedException: sleep interrupted
	at InterruptTest.lambda$main$0(InterruptTest.java:17)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.InterruptedException: sleep interrupted
	at java.base/java.lang.Thread.sleep(Native Method)
	at java.base/java.lang.Thread.sleep(Thread.java:334)
	at java.base/java.util.concurrent.TimeUnit.sleep(TimeUnit.java:446)
	at InterruptTest.lambda$main$0(InterruptTest.java:15)
	... 1 more
Process finished with exit code 0

兩階段終止模式 Two Phase Termination

在線程t1中如何優(yōu)雅的終止線程t2?

  • 使用stop()方法終止線程,這顯然是不好的行為,因?yàn)橐粋€(gè)線程調(diào)用了stop()方法,那么這個(gè)線程就被徹底殺死了,如果該線程正在訪問一些共享資源并且加了鎖,那么stop()之后該線程將再也不能釋放鎖,其他線程也就無法訪問那些共享資源了。
  • 使用System.exit()方法,這也是錯(cuò)誤的選擇,這會(huì)終止整個(gè)程序!

正確的做法是采用兩階段終止模式,具體流程如下圖所示:

import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@Slf4j
public class TwoPhaseTest {
    public static void main(String[] args) throws InterruptedException {
        TwoPhaseTermination tpt = new TwoPhaseTermination();
        tpt.start();
        TimeUnit.SECONDS.sleep(4);
        tpt.stop();
    }
}
/**
 * 監(jiān)控類
 */
@Slf4j
class TwoPhaseTermination{
    //監(jiān)控線程
    private Thread monitor;
    //線程啟動(dòng)方法
    public void start(){
        monitor = new Thread(()->{
            while(true){
                Thread thread = Thread.currentThread();
                Boolean interrupted = thread.isInterrupted();
                if(interrupted){
                    log.debug("料理后事.....");
                    break;
                }
                try {
                    TimeUnit.SECONDS.sleep(1);
                    //每隔一秒鐘執(zhí)行監(jiān)控任務(wù)
                    log.debug("監(jiān)控中....");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    //如果在sleep狀態(tài)被打斷,那么中斷標(biāo)記為false,需要手動(dòng)置為true
                    thread.interrupt();
                }
        }});
        //啟動(dòng)線程
        monitor.start();
    }
    //線程終止方法
    public void stop(){
        //打斷線程
        monitor.interrupt();
    }
}

15:38:11.046 [Thread-0] DEBUG TwoPhaseTermination - 監(jiān)控中....
15:38:12.054 [Thread-0] DEBUG TwoPhaseTermination - 監(jiān)控中....
15:38:13.060 [Thread-0] DEBUG TwoPhaseTermination - 監(jiān)控中....
java.lang.InterruptedException: sleep interrupted
    at java.base/java.lang.Thread.sleep(Native Method)
    at java.base/java.lang.Thread.sleep(Thread.java:334)
    at java.base/java.util.concurrent.TimeUnit.sleep(TimeUnit.java:446)
    at TwoPhaseTermination.lambda$start$0(TwoPhaseTest.java:33)
    at java.base/java.lang.Thread.run(Thread.java:829)
15:38:14.014 [Thread-0] DEBUG TwoPhaseTermination - 料理后事.....

Process finished with exit code 0

打斷park()線程

import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
@Slf4j
public class ParkTest {
    public static void main(String[] args) throws InterruptedException {
        test();
    }
    private static void test() throws InterruptedException {
        Thread t1 = new Thread(()->{
           log.debug("park......");
           LockSupport.park();//線程在此卡住,不繼續(xù)向下執(zhí)行
           log.debug("unpark.......");
           log.debug("打斷狀態(tài):{}",Thread.currentThread().isInterrupted());
        },"t1");
        t1.start();
        //主線程main休眠2秒
        TimeUnit.SECONDS.sleep(2);
        //打斷t1線程
        t1.interrupt();
    }
}

15:51:24.581 [t1] DEBUG ParkTest - park......
15:51:26.582 [t1] DEBUG ParkTest - unpark.......
15:51:26.584 [t1] DEBUG ParkTest - 打斷狀態(tài):true

到此這篇關(guān)于Java并發(fā)編程 interrupt()方法的文章就介紹到這了,更多相關(guān)Java并發(fā)編程 interrupt()方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • GateWay路由規(guī)則與動(dòng)態(tài)路由詳細(xì)介紹

    GateWay路由規(guī)則與動(dòng)態(tài)路由詳細(xì)介紹

    這篇文章主要介紹了GateWay路由規(guī)則與GateWay動(dòng)態(tài)路由,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • springboot集成flyway自動(dòng)創(chuàng)表的詳細(xì)配置

    springboot集成flyway自動(dòng)創(chuàng)表的詳細(xì)配置

    Flayway是一款數(shù)據(jù)庫版本控制管理工具,支持?jǐn)?shù)據(jù)庫版本自動(dòng)升級(jí),Migrations可以寫成sql腳本,也可以寫在java代碼里;本文通過實(shí)例代碼給大家介紹springboot集成flyway自動(dòng)創(chuàng)表的詳細(xì)過程,感興趣的朋友一起看看吧
    2021-06-06
  • SpringBoot整合MinIO實(shí)現(xiàn)文件存儲(chǔ)系統(tǒng)的代碼示例

    SpringBoot整合MinIO實(shí)現(xiàn)文件存儲(chǔ)系統(tǒng)的代碼示例

    在現(xiàn)代的應(yīng)用程序中,文件存儲(chǔ)和管理是一個(gè)常見的需求,MinIO是一個(gè)開源的對(duì)象存儲(chǔ)系統(tǒng),與Spring?Boot框架結(jié)合使用,可以快速構(gòu)建高性能的文件存儲(chǔ)系統(tǒng),本文將介紹如何使用Spring?Boot和MinIO來實(shí)現(xiàn)文件存儲(chǔ)系統(tǒng)
    2023-06-06
  • Spring Boot 實(shí)現(xiàn)Restful webservice服務(wù)端示例代碼

    Spring Boot 實(shí)現(xiàn)Restful webservice服務(wù)端示例代碼

    這篇文章主要介紹了Spring Boot 實(shí)現(xiàn)Restful webservice服務(wù)端示例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-11-11
  • spring-boot-maven-plugin:unknown的完美解決方法

    spring-boot-maven-plugin:unknown的完美解決方法

    這篇文章主要介紹了spring-boot-maven-plugin:unknown的完美解決方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • 使用System.exit()來優(yōu)雅地終止SpringBoot項(xiàng)目的代碼示例

    使用System.exit()來優(yōu)雅地終止SpringBoot項(xiàng)目的代碼示例

    System.exit() 方法是 Java 中用于退出程序的方法,它接受一個(gè)整數(shù)參數(shù),通常被用來指示程序的退出狀態(tài),本文給大家介紹了如何使用System.exit()來優(yōu)雅地終止SpringBoot項(xiàng)目,需要的朋友可以參考下
    2024-08-08
  • postman測試傳入List<String>參數(shù)方式

    postman測試傳入List<String>參數(shù)方式

    這篇文章主要介紹了postman測試傳入List<String>參數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java類成員訪問權(quán)限控制知識(shí)總結(jié)

    Java類成員訪問權(quán)限控制知識(shí)總結(jié)

    這篇文章主要介紹了Java類成員訪問權(quán)限控制知識(shí)總結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Mybatis實(shí)現(xiàn)動(dòng)態(tài)建表代碼實(shí)例

    Mybatis實(shí)現(xiàn)動(dòng)態(tài)建表代碼實(shí)例

    這篇文章主要介紹了Mybatis實(shí)現(xiàn)動(dòng)態(tài)建表代碼實(shí)例,解釋一下,就是指根據(jù)傳入的表名,動(dòng)態(tài)地創(chuàng)建數(shù)據(jù)庫表,以供后面的業(yè)務(wù)場景使用,
    而使用 Mybatis 的動(dòng)態(tài) SQL,就能很好地為我們解決這個(gè)問題,需要的朋友可以參考下
    2023-10-10
  • spring的xml文件打開沒有namespace等操作選項(xiàng)的解決方案

    spring的xml文件打開沒有namespace等操作選項(xiàng)的解決方案

    這篇文章主要介紹了spring的xml文件打開沒有namespace等操作選項(xiàng)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評(píng)論