国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Java并發(fā)編程】線程中斷機(jī)制(輔以常見案例)

這篇具有很好參考價(jià)值的文章主要介紹了【Java并發(fā)編程】線程中斷機(jī)制(輔以常見案例)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。


本文由淺入深介紹了中斷機(jī)制、中斷的常見案例和使用場景。

1. 為什么需要

因?yàn)橐恍┰蛐枰∠菊趫?zhí)行的線程。我們舉幾個(gè)栗子:

  • 假設(shè)踢足球點(diǎn)球時(shí),A隊(duì)前4輪中了4個(gè)球,B隊(duì)前4輪只中了2個(gè)球,此時(shí)勝負(fù)已分,第5輪這個(gè)點(diǎn)球就不用踢了,此時(shí)需要停止A隊(duì)的線程和B隊(duì)的線程(共5個(gè)點(diǎn)球)。
  • 假設(shè)用戶從網(wǎng)絡(luò)上下載一個(gè)50M的文件,如果網(wǎng)絡(luò)很慢,用戶等的不耐煩,點(diǎn)了取消下載操作,此時(shí)需要停止下載的線程。

2. 如何理解

中斷可以理解為線程的一個(gè)內(nèi)部標(biāo)識(shí)位屬性,它表示一個(gè)運(yùn)行中的線程是否被其他線程進(jìn)行了中斷操作。

中斷就是其他線程通過interrupt方法給該線程發(fā)一個(gè)信號(hào),該線程收到信號(hào)后可以選擇響應(yīng)或不響應(yīng)信號(hào),中斷它只是一種協(xié)商機(jī)制。響應(yīng)信號(hào)通常會(huì)結(jié)束自身run()方法的執(zhí)行退出線程,不響應(yīng)則繼續(xù)執(zhí)行無任何影響。

線程通過檢測自身是否被中斷來進(jìn)行響應(yīng),檢測方法有2種,分別是public static boolean interrupted()public boolean isInterrupted(),靜態(tài)的方法會(huì)清除中斷標(biāo)識(shí)位屬性,非靜態(tài)方法不會(huì)清除中斷標(biāo)識(shí)位屬性。

3. 如何使用

3.1. 中斷相關(guān)API

Thread源碼中關(guān)于中斷的方法:

public class Thread implements Runnable {
    
    // 僅僅只是設(shè)置中斷狀態(tài)
    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();
    }
    
	// 會(huì)清除中斷狀態(tài)
	public static boolean interrupted() {
		return currentThread().isInterrupted(true);
	}
    
	// 不會(huì)清除中斷狀態(tài)
	public boolean isInterrupted() {
		return isInterrupted(false);
	}
    
    private native void interrupt0();
    
    private native boolean isInterrupted(boolean ClearInterrupted);
}

繪制成表格:

API 作用
public void interrupt() 中斷this線程
public static boolean interrupted() 測試當(dāng)前線程是否被中斷,且線程的中斷狀態(tài)會(huì)被清除
public boolean isInterrupted() 測試this線程是否中斷。 中斷狀態(tài)不會(huì)被這個(gè)方法影響

特別需要注意的是:靜態(tài)interrupted方法會(huì)清除線程的中斷狀態(tài)。

3.2. 中斷正常狀態(tài)下的線程

中斷一個(gè)線程非常簡單,只需要在其他線程中對(duì)目標(biāo)線程調(diào)用interrupt()方法,目標(biāo)線程需要反復(fù)檢測自身狀態(tài)是否是interrupted狀態(tài),如果是,就立刻結(jié)束運(yùn)行。

public class Main extends Thread {
    @Override
    public void run() {
        int i = 0;
        while (!Thread.currentThread().isInterrupted()) {
            i++;
            System.out.println();
        }
        System.out.println("done");
    }
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Main();
        t.start();
        t.sleep(1000);
        t.interrupt();
    }
}

main線程通過調(diào)用t.interrupt()中斷t線程。但需要注意,interrupt()方法僅僅是給t線程發(fā)送了"中斷請(qǐng)求",只是把t線程的標(biāo)識(shí)屬性設(shè)置為中斷,至于t線程是否響應(yīng)或處理該中斷請(qǐng)求則要看t線程的具體代碼。

這里,t線程在while中循環(huán)檢測中斷請(qǐng)求(isInterrupted()),如果檢測到線程被中斷則跳出while循環(huán)結(jié)束線程的run()方法。

3.3. 中斷特殊狀態(tài)下的線程

特殊狀態(tài)其實(shí)在官網(wǎng)Thread中有好幾種,這里只列舉最常見的一種

如果線程

  • 被阻塞在Object類的wait(),wait(long)wait(long, int)方法
  • 或被阻塞在Thread類的join(),join(long)join(long, int),sleep(long),sleep(long, int)

如果此時(shí)調(diào)用線程的中斷方法interrupt(),線程的中斷狀態(tài)會(huì)被清除且拋出InterruptedException異常。這種情況的一般處理方法是:捕獲InterruptedException異常,然后重新設(shè)置中斷狀態(tài),即調(diào)用Thread.currentThread().interrupt();

我們來看示例代碼:

public class Main extends Thread {
    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                // 模擬任務(wù)代碼
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // ... 清理操作
                System.out.println(isInterrupted());//false
                // 重設(shè)中斷標(biāo)志位為true
                Thread.currentThread().interrupt();
            }
        }
        System.out.println(isInterrupted());//true
    }

    public static void main(String[] args) {
        Main t = new Main();
        t.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
        }
        t.interrupt();
    }
}

4. 如何安全的停止線程

前面提到中斷狀態(tài)只是線程的一個(gè)標(biāo)識(shí)位,而中斷操作是一種簡便的線程間交互方式,而這種交互方式最適合用來取消或停止任務(wù)。除了中斷以外,還可以利用一個(gè)boolean變量來控制是否需要停止任務(wù)并終止該線程。 一般的,可以用以下方式來安全的停止線程:

  • 中斷方式
  • volatile修飾的boolean變量方式

代碼舉例如下:

public class Shutdown {
	public static void main(String[] args) throws Exception {
		Runner one = new Runner();
		Thread t = new Thread(one, "t");
		t.start();
		// 睡眠1秒,讓Runner線程充分運(yùn)行,隨后能夠感知中斷而結(jié)束
		TimeUnit.SECONDS.sleep(1);
		t.interrupt();
        
        
		Runner two = new Runner();
		t = new Thread(two, "t");
		t.start();
		// 睡眠1秒,讓Runner線程充分運(yùn)行,隨后能夠感知on為false而結(jié)束
		TimeUnit.SECONDS.sleep(1);
		two.cancel();
	}

	private static class Runner implements Runnable {
		private long i;

		private volatile boolean on = true;

		@Override
		public void run() {
			while (on && !Thread.currentThread().isInterrupted()) {
				i++;
			}
			System.out.println("Count i = " + i);
		}

		public void cancel() {
			on = false;
		}
	}
}

5. 參考資料

《Java并發(fā)編程的藝術(shù)》,可聯(lián)系作者無套路下載可復(fù)制的電子版pdf書籍

官方Thread類的源碼和注釋文章來源地址http://www.zghlxwxcb.cn/news/detail-643031.html

到了這里,關(guān)于【Java并發(fā)編程】線程中斷機(jī)制(輔以常見案例)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Java 并發(fā)編程】一文讀懂線程、協(xié)程、守護(hù)線程

    【Java 并發(fā)編程】一文讀懂線程、協(xié)程、守護(hù)線程

    在 Java 線程的生命周期一文中提到了 就緒狀態(tài)的線程在獲得 CPU 時(shí)間片后變?yōu)檫\(yùn)行中狀態(tài) ,否則就會(huì)在 可運(yùn)行狀態(tài) 或者 阻塞狀態(tài) ,那么系統(tǒng)是如何分配線程時(shí)間片以及實(shí)現(xiàn)線程的調(diào)度的呢?下面我們就來講講線程的調(diào)度策略。 線程調(diào)度是指系統(tǒng)為線程分配 CPU 執(zhí)行時(shí)間片

    2023年04月08日
    瀏覽(24)
  • 【Java并發(fā)編程】變量的線程安全分析

    【Java并發(fā)編程】變量的線程安全分析

    1.成員變量和靜態(tài)變量是否線程安全? 如果他們沒有共享,則線程安全 如果被共享: 只有讀操作,則線程安全 有寫操作,則這段代碼是臨界區(qū),需要考慮線程安全 2.局部變量是否線程安全 局部變量是線程安全的 當(dāng)局部變量引用的對(duì)象則未必 如果給i對(duì)象沒有逃離方法的作用

    2024年02月08日
    瀏覽(91)
  • Java面試_并發(fā)編程_線程基礎(chǔ)

    Java面試_并發(fā)編程_線程基礎(chǔ)

    進(jìn)程是正在運(yùn)行程序的實(shí)例, 進(jìn)程中包含了線程, 每個(gè)線程執(zhí)行不同的任務(wù) 不同的進(jìn)程使用不同的內(nèi)存空間, 在當(dāng)前進(jìn)程下的所有線程可以共享內(nèi)存空間 線程更輕量, 線程上下文切換成本一般上要比進(jìn)程上下文切換低(上下文切換指的是從一個(gè)線程切換到另一個(gè)線程) 并發(fā)是單個(gè)

    2024年02月07日
    瀏覽(30)
  • 【Java 并發(fā)編程】Java 線程本地變量 ThreadLocal 詳解

    【Java 并發(fā)編程】Java 線程本地變量 ThreadLocal 詳解

    先一起看一下 ThreadLocal 類的官方解釋: 用大白話翻譯過來,大體的意思是: ThreadLoal 提供給了 線程局部變量 。同一個(gè) ThreadLocal 所包含的對(duì)象,在不同的 Thread 中有不同的副本。這里有幾點(diǎn)需要注意: 因?yàn)槊總€(gè) Thread 內(nèi)有自己的實(shí)例副本,且 該副本只能由當(dāng)前 Thread 使用 。

    2024年02月04日
    瀏覽(31)
  • java并發(fā)編程:多線程基礎(chǔ)知識(shí)介紹

    最初的計(jì)算機(jī)只能接受一些特定的指令,用戶每輸入一個(gè)指令,計(jì)算機(jī)就做出一個(gè)操作。當(dāng)用戶在思考或者輸入時(shí),計(jì)算機(jī)就在等待。這樣效率非常低下,在很多時(shí)候,計(jì)算機(jī)都處在等待狀態(tài)。 后來有了 批處理操作系統(tǒng) ,把一系列需要操作的指令寫下來,形成一個(gè)清單,一次

    2024年02月07日
    瀏覽(21)
  • java語法(二)線程并發(fā)、Juit單元測試、反射機(jī)制、注解、動(dòng)態(tài)代理、XML解析、JVM

    java語法(二)線程并發(fā)、Juit單元測試、反射機(jī)制、注解、動(dòng)態(tài)代理、XML解析、JVM

    正則表達(dá)式驗(yàn)證網(wǎng)站 1、 ? :表示前邊這個(gè)字符可以出現(xiàn)0次或者1次。例如下邊 /used? 既可以匹配 use 也可以匹配 used 。 2、 * :匹配0個(gè)或者多個(gè)字符, * 號(hào)代表前邊這個(gè)字符可以出現(xiàn)0次或者多次。例如 /ab*c 可以匹配 ac、abc、abbbbc 3、 + :與 * 號(hào)不同的是, + 需要前面這個(gè)字符

    2024年02月06日
    瀏覽(25)
  • Java并發(fā)編程第6講——線程池(萬字詳解)

    Java并發(fā)編程第6講——線程池(萬字詳解)

    Java中的線程池是運(yùn)用場景最多的并發(fā)框架,幾乎所有需要異步或并發(fā)執(zhí)行任務(wù)的程序都可以使用線程池,本篇文章就詳細(xì)介紹一下。 定義:線程池是一種用于管理和重用線程的技術(shù)(池化技術(shù)),它主要用于提高多線程應(yīng)用程序的性能和效率。 ps:線程池、連接池、內(nèi)存池

    2024年02月11日
    瀏覽(27)
  • Java并發(fā)編程學(xué)習(xí)18-線程池的使用(下)

    上篇介紹了 ThreadPoolExecutor 配置和擴(kuò)展相關(guān)的信息,本篇開始將介紹遞歸算法的并行化。 還記得我們在《Java并發(fā)編程學(xué)習(xí)11-任務(wù)執(zhí)行演示》中,對(duì)頁面繪制程序進(jìn)行一系列改進(jìn),這些改進(jìn)大大地提供了頁面繪制的并行性。 我們簡單回顧下相關(guān)的改進(jìn)過程: 第一次新增時(shí),頁

    2024年02月12日
    瀏覽(24)
  • Java并發(fā)編程學(xué)習(xí)16-線程池的使用(中)

    Java并發(fā)編程學(xué)習(xí)16-線程池的使用(中)

    上篇分析了在使用任務(wù)執(zhí)行框架時(shí)需要注意的各種情況,并簡單介紹了如何正確調(diào)整線程池大小。 本篇將繼續(xù)介紹對(duì)線程池進(jìn)行配置與調(diào)優(yōu)的一些方法,詳細(xì)如下: ThreadPoolExecutor 為 Executors 中的 newCachedThreadPool 、 newFixedThreadPool 和 newScheduledThreadExecutor 等工廠方法返回的 Exe

    2024年02月10日
    瀏覽(18)
  • Java并發(fā)編程學(xué)習(xí)筆記(一)線程的入門與創(chuàng)建

    Java并發(fā)編程學(xué)習(xí)筆記(一)線程的入門與創(chuàng)建

    認(rèn)識(shí) 程序由指令和數(shù)據(jù)組成,簡單來說,進(jìn)程可以視為程序的一個(gè)實(shí)例 大部分程序可以同時(shí)運(yùn)行多個(gè)實(shí)例進(jìn)程,例如記事本、畫圖、瀏覽器等 少部分程序只能同時(shí)運(yùn)行一個(gè)實(shí)例進(jìn)程,例如QQ音樂、網(wǎng)易云音樂等 一個(gè)進(jìn)程可以分為多個(gè)線程,線程為最小調(diào)度單位,進(jìn)程則是作

    2024年02月16日
    瀏覽(48)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包