最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

interrupt()用法

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

interrrupt()方法可以用來(lái)打斷正在運(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();
    }
}

通過(guò)控制臺(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線程自己覺(jué)得是繼續(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è)線程就被徹底殺死了,如果該線程正在訪問(wèn)一些共享資源并且加了鎖,那么stop()之后該線程將再也不能釋放鎖,其他線程也就無(wú)法訪問(wèn)那些共享資源了。
  • 使用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)文章

  • MyBatis使用CASE WHEN進(jìn)行批量更新的高效寫法

    MyBatis使用CASE WHEN進(jìn)行批量更新的高效寫法

    當(dāng)我們使用mybatis的時(shí)候,可能經(jīng)常會(huì)碰到一批數(shù)據(jù)的批量更新問(wèn)題,因?yàn)槿绻粭l數(shù)據(jù)一更新,那每一條數(shù)據(jù)就需要涉及到一次數(shù)據(jù)庫(kù)的操作,包括網(wǎng)絡(luò)IO以及磁盤IO,可想而知,這個(gè)效率是非常低下的,那么今天我們就來(lái)總結(jié)一下,如何使用mybatis做批量更新,需要的朋友可以參考下
    2025-10-10
  • SpringBoot+Redis實(shí)現(xiàn)數(shù)據(jù)字典的方法

    SpringBoot+Redis實(shí)現(xiàn)數(shù)據(jù)字典的方法

    這篇文章主要介紹了SpringBoot+Redis實(shí)現(xiàn)數(shù)據(jù)字典的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • 基于Spring-cloud-gateway實(shí)現(xiàn)全局日志記錄的方法

    基于Spring-cloud-gateway實(shí)現(xiàn)全局日志記錄的方法

    最近項(xiàng)目在線上運(yùn)行出現(xiàn)了一些難以復(fù)現(xiàn)的bug需要定位相應(yīng)api的日志,通過(guò)nginx提供的api請(qǐng)求日志難以實(shí)現(xiàn),于是在gateway通過(guò)全局過(guò)濾器記錄api請(qǐng)求日志,本文給大家介紹基于Spring-cloud-gateway實(shí)現(xiàn)全局日志記錄,感興趣的朋友一起看看吧
    2023-11-11
  • Spring構(gòu)造器注入及@Autowired、lombok的@RequiredArgsConstructor的異同點(diǎn)說(shuō)明

    Spring構(gòu)造器注入及@Autowired、lombok的@RequiredArgsConstructor的異同點(diǎn)說(shuō)明

    本文介紹了Spring框架中構(gòu)造器注入的實(shí)現(xiàn)原理,包括Spring如何找到參數(shù)、構(gòu)造器注入與Autowired的區(qū)別,以及為什么Spring官方推薦構(gòu)造器注入,文章還強(qiáng)調(diào)了構(gòu)造器注入中使用final關(guān)鍵字的好處,并提供了代碼示例,幫助讀者更好地理解和應(yīng)用Spring的最佳實(shí)踐
    2026-03-03
  • Spring?Boot?Shiro?auto-configure工作流程詳解

    Spring?Boot?Shiro?auto-configure工作流程詳解

    這篇文章主要為大家介紹了Spring?Boot?Shiro?auto-configure工作流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • SpringCloud組件之Eureka Server詳細(xì)啟動(dòng)過(guò)程及說(shuō)明

    SpringCloud組件之Eureka Server詳細(xì)啟動(dòng)過(guò)程及說(shuō)明

    這篇文章主要介紹了SpringCloud組件之Eureka Server詳細(xì)啟動(dòng)過(guò)程及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Netty事件循環(huán)主邏輯NioEventLoop的run方法分析

    Netty事件循環(huán)主邏輯NioEventLoop的run方法分析

    這篇文章主要介紹了Netty事件循環(huán)主邏輯NioEventLoop的run方法分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • 詳解Java中LinkedHashMap

    詳解Java中LinkedHashMap

    本文主要介紹了Java中LinkedHashMap的相關(guān)知識(shí),具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-05-05
  • idea搭建ssh框架的超詳細(xì)教程

    idea搭建ssh框架的超詳細(xì)教程

    這篇文章主要介紹了idea搭建ssh框架的超詳細(xì)教程,本文通過(guò)圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Java的云打印Lodop

    Java的云打印Lodop

    這篇文章主要介紹了Java的云打印Lodop 的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07

最新評(píng)論

福泉市| 鹿泉市| 彭山县| 无棣县| 那坡县| 满洲里市| 富民县| 申扎县| 疏附县| 澄江县| 博野县| 日照市| 昭苏县| 塘沽区| 镇巴县| 漳浦县| 贵溪市| 鄂伦春自治旗| 鄄城县| 南川市| 建湖县| 新建县| 宜兴市| 自贡市| 项城市| 三亚市| 巴林右旗| 新泰市| 沈丘县| 菏泽市| 宽甸| 集安市| 五华县| 汤原县| 贵溪市| 岚皋县| 朔州市| 财经| 额敏县| 汉寿县| 广丰县|