久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

線程中斷以及線程中斷引發(fā)的那些問題,你值得了解

 xkl135 2018-09-09

上周寫了一篇多線程的文章,,其實(shí)更多方面是偏基礎(chǔ)一點(diǎn)的文章,,而且也比較大白話,爭取人人都能看的明白,,再舉一些常見的例子,,能很好的幫助大家理解多線程,文章發(fā)表之后我投給了幾個(gè)大號和CSDN反應(yīng)都挺好的,,大家表示希望能寫更多這樣的文章,,希望再多寫寫線程相關(guān)的文章,所以我打算從線程的基礎(chǔ)開始寫起,,每周寫那么兩三篇,,大家閑的時(shí)候可以看看,也可以多吸收一點(diǎn)東西,。


另外,,希望大家在閱讀完之后能來個(gè)互動點(diǎn)贊什么的,也讓我有點(diǎn)創(chuàng)作的動力,,另外說說你們的想法什么的,,我也好寫出更好的文章來,廢話不多說了,,我們開始今天的知識點(diǎn)學(xué)習(xí)吧,!


什么是線程中斷?

在我們的Java程序中其實(shí)有不止一條執(zhí)行線程,,只有當(dāng)所有的線程都運(yùn)行結(jié)束的時(shí)候,,這個(gè)Java程序才算運(yùn)行結(jié)束。

官方的話給你描述一下:當(dāng)所有的非守護(hù)線程運(yùn)行結(jié)束時(shí),,或者其中一個(gè)線程調(diào)用了System.exit()方法時(shí),,這個(gè)Java程序才能運(yùn)行結(jié)束。


線程中斷的應(yīng)用場景

我們先來舉一個(gè)例子,,比如我們現(xiàn)在在下載一個(gè)500多M的大片,,我們點(diǎn)擊開始下載,那個(gè)這個(gè)時(shí)候就等于開啟了一個(gè)線程去下載我們的文件,,然而這個(gè)時(shí)候我們的網(wǎng)速不是很給力,,幾十KB的在這跑,作為一個(gè)年輕人我是等不了了,我不下來,,那么這個(gè)時(shí)候我們第一個(gè)操作就是結(jié)束掉這個(gè)下載文件的操作,,其實(shí)更接近程序的來說,這個(gè)時(shí)候我們就需要把這個(gè)線程給中斷了,。



我們接下來寫一下這個(gè)下載的代碼,,看一下如何中斷一個(gè)線程,這里我已經(jīng)默認(rèn)你們已經(jīng)掌握了如何創(chuàng)建一個(gè)線程了,這段程序我們模擬下載,,最開始獲取系統(tǒng)時(shí)間,,然后進(jìn)入循環(huán)每次獲取系統(tǒng)時(shí)間,如果時(shí)間超過10秒我們就中斷線程,,不在繼續(xù)下載,,下載速度時(shí)每秒1M:

public void run({

       int number = 0;

       // 記錄程序開始的時(shí)間
       Long start = System.currentTimeMillis();

       while (true) {

           // 每次執(zhí)行一次結(jié)束的時(shí)間
           Long end = System.currentTimeMillis();

           // 獲取時(shí)間差
           Long interval = end - start;

           // 如果時(shí)間超過了10秒,那么我們就結(jié)束下載
           if (interval >= 10000) {
               // 中斷線程
               interrupted();
               System.err.println('太慢了,,我不下了');
               return;
           } else if (number >= 500) {
               System.out.println('文件下載完成');
               // 中斷線程
               interrupted();
               return;
           }

           number ;
           System.out.println('已下載'  number  'M');

           try {
               Thread.sleep(2000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
   }


中斷線程的方式

Thread類中給我們提供了中斷線程的方法,,我們先來看下這個(gè)方法到底是如何讓線程中斷的:

public static boolean interrupted() {
       return currentThread().isInterrupted(true);
   }


這個(gè)方法是檢查當(dāng)前線程是否被中斷,中斷返回true,,未中斷返回false

private native boolean isInterrupted(boolean ClearInterrupted);


通過查看源碼我們可以發(fā)現(xiàn),,中斷線程就是通過調(diào)用檢查線程是否被中斷的方法,把值設(shè)為true,。這個(gè)時(shí)候你再去調(diào)用檢查線程是否中斷的方法時(shí)就返回true了,。


這里大家需要注意一個(gè)問題:Thread.interrupted()方法只是修改了當(dāng)前線程的狀態(tài)告訴他被中斷了,但是對于非阻塞中的線程,,只是改變了中斷狀態(tài),,即

Thread.isInterrupted()返回true,對于可取消的阻塞狀態(tài)中的線程,,例如等待在這些函數(shù)上的線程 ,,Thread.sleep(),這個(gè)線程收到中斷信號之后就會拋出InterruptedException異常,,同時(shí)會把中斷狀態(tài)設(shè)置為true,。


線程睡眠引起InterruptedException異常的原因

其實(shí)這樣說大家也是一知半解,我就寫一個(gè)錯誤的示例,,大家來看一下,,把這個(gè)問題徹底的搞清楚:

public void run({

       int number = 0;

       while (true) {
           // 檢查線程是否被中斷,中斷就停止下載
           if (isInterrupted()) {

               System.err.println('太慢了,,我不下了');
               return;
           } else if (number >= 500) {
               System.out.println('下載完成');
               return;
           }

           number ;
           System.out.println('已下載'  number  'M');

           try {
               Thread.sleep(2000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
   }



這是我們的主程序,,等待10秒后中斷線程

public static void main(String[] args) throws InterruptedException {

       Thread thread = new PrimeGenerator();

       // 啟動線程
       thread.start();

       // 等待10秒后中斷線程
       Thread.sleep(1000);

       // 中斷線程
       thread.interrupt();
   }


看起來很通常的一個(gè)程序,但是事實(shí)卻并非你看到的樣子,,其實(shí)這段代碼是會拋出InterruptedException異常的,,我們來分析原因。



這里我們先要了解Thread.interrupt()方法不會中斷一個(gè)正在運(yùn)行的線程,調(diào)用Thread.sleep()方法時(shí),,這個(gè)時(shí)候就不再占用CPU,我們來分析下我們這個(gè)程序,,我們下載是要等待10秒,,每次下載的速度是0.5M/S,也就是當(dāng)我們下載到5M的時(shí)候等待時(shí)間已經(jīng)到了,,這個(gè)時(shí)候調(diào)用Thread.interrupt()方法中斷線程,,但是run()方法中的睡眠還要接著往下執(zhí)行,它是不會因?yàn)橹袛喽艞増?zhí)行下面的代碼的,,那么這個(gè)時(shí)候當(dāng)它再執(zhí)行Thread.sleep()的時(shí)候就會拋出InterruptedException異常,,因?yàn)楫?dāng)前的線程已經(jīng)被中斷了。


說到這里,,你是否已經(jīng)明白產(chǎn)生這個(gè)異常的原因了,?另外還有另外的兩個(gè)原因致使線程產(chǎn)生InterruptedException異常的原因,wait(),、join()兩個(gè)方法使用不當(dāng)也會引起線程拋出該異常,。


查看線程是否中斷的兩種方式

在Thread類中有一個(gè)方法interrupted()可以用來檢查當(dāng)前線程時(shí)候被中斷,還有isInterrupted()方法可以用來檢查當(dāng)前線程是否被中斷,。


中斷線程的方法其實(shí)底層就是將這個(gè)屬性設(shè)置為true,,isInterrupted()方法只是返回了這個(gè)屬性值而已。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多