<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    中文JAVA技術(shù)平等自由協(xié)作創(chuàng)造

    Java專題文章博客和開源

    常用鏈接

    統(tǒng)計(jì)

    最新評(píng)論

    Java 基本功之中斷線程的理解

      設(shè)想這樣的情景:我們的應(yīng)用在某一個(gè)時(shí)間段內(nèi),需要一個(gè)子線程不停的在后臺(tái)運(yùn)行,這可能是一個(gè)下載過程,是一個(gè)對(duì)服務(wù)端socket的監(jiān)聽,也可能是一個(gè)繪圖的計(jì)算過程。當(dāng)我們想要終止線程的時(shí)候,我們會(huì)怎樣做呢?是設(shè)定一個(gè)標(biāo)志變量來控制跳出循環(huán)?還是使用thread.stop()?又或者是設(shè)置thread = null?
       有的時(shí)候我們需要一種規(guī)范的思路,使用規(guī)范的方法來解決一類問題。
       我們首先要明白,線程終止的條件,有三種情況:
       1.當(dāng)線程的run方法執(zhí)行方法體中最后一條語句后。
       2.當(dāng)執(zhí)行retutrn語句返回時(shí)。
       3.當(dāng)出現(xiàn)了在方法中沒有捕獲的異常時(shí)。
       在Java的早期版本中,還有一個(gè)stop方法,其他線程可以調(diào)用它終止線程,但是這個(gè)方法已經(jīng)被棄用了,所以還在用的同學(xué)就不要繼續(xù)用了。
       我們的正確思路是,使用interrupt方法來終止我們的線程www.sats686.com
       首先要理解interrupt方法做了什么:每一個(gè)線程都有一個(gè)中斷狀態(tài),這是一個(gè)boolean標(biāo)志,當(dāng)線程調(diào)用了interrupt方法時(shí),這個(gè)中斷狀態(tài)就會(huì)被置位。如果我們要檢查中斷狀態(tài),可以使用Thread.currentThread()。isInterrupted()來獲得是否中斷。
       但是如果線程被阻塞了(sleep or wait),當(dāng)我們調(diào)用了interrupt方法的時(shí)候,就會(huì)產(chǎn)生InterruptedException異常。這是我們可以利用的地方。
       同樣的,如果中斷狀態(tài)先被置位了,然后我們調(diào)用了sleep方法,線程不會(huì)休眠,相反,它將清除中斷狀態(tài),然后拋出InterruptedException.
       我們調(diào)用了interrupt并不意味著線程會(huì)終止,線程是否會(huì)終止,以及會(huì)如何繼續(xù),是程序員來控制的托福答案
       在本文中我們將會(huì)討論終止線程的規(guī)范用法,然后在一個(gè)例子中實(shí)際應(yīng)用,在這個(gè)例子中我們模擬了文件拷貝和游戲繪圖兩種情形。做出的效果如下圖所示,點(diǎn)擊start后上方進(jìn)度條會(huì)顯示文件拷貝的進(jìn)度,點(diǎn)擊end則會(huì)停止拷貝。點(diǎn)擊draw會(huì)在畫面中不停繪制各種各樣的矩形,點(diǎn)擊stop則會(huì)停止繪制。
       首先我們來看兩種情形的后臺(tái)線程寫法:
       public void run() {
       try{
       …
       while(!Thread.currentThread.isInterrupted() && more work to do)
       {
       do more work
       }
       }
       catch(InterruptedException)
       {
       //thread was interrupted during sleep or wait
       }
       finally
       {
       cleanup, if required
       }
       //exiting the run method terminates the thread }
       public void run() {
       try{
       …
       while( more work to do)
       {
       do more work
       Thread.sleep(delay);
       }
       }
       catch(InterruptedException)
       {
       //thread was interrupted during sleep or wait
       }
       finally
       {
       cleanup, if required
       }
       //exiting the run method terminates the thread }
       第一種寫法適用于后臺(tái)下載,文件拷貝以及類似情形,第二種寫法適合游戲畫面刷新或者類似情形。
       第一種寫法利用了interrupt方法,作為終止的請(qǐng)求,使得循環(huán)跳出,run方法執(zhí)行完畢。而第二種方法則是利用當(dāng)線程sleep的時(shí)候調(diào)用interrupt會(huì)拋出InterruptedException從而跳出了循環(huán)進(jìn)而線程執(zhí)行到結(jié)束www.yxysedu.com
       事實(shí)上這兩種寫法的區(qū)別就在于第二種使用了sleep.
       在我們的使用示例中,對(duì)應(yīng)這兩種方法的使用代碼如下:
       這一段是實(shí)現(xiàn)文件拷貝的:
       private class CopyRunnable implements Runnable {
       @Override
       public void run() {
       File fromFile = new File(Environment.getExternalStorageDirectory()
       .getAbsolutePath() + "/abc.exe");
       long fileLength = fromFile.length();
       long copyedLength = 0;
       File toFile = new File(Environment.getExternalStorageDirectory()
       .getAbsolutePath() + "/abc_.exe");
       if (toFile.exists()) {
       toFile.delete();
       }
       try {
       FileInputStream fileInputStream = new FileInputStream(fromFile);
       FileOutputStream fileOutputStream = new FileOutputStream(
       toFile, true);
       byte[] buffer = new byte[2048];
       int readLength = 0;
       while (!Thread.currentThread()。isInterrupted()
       && (readLength = fileInputStream.read(buffer)) != -1) {
       fileOutputStream.write(buffer, 0, buffer.length);
       copyedLength += readLength;
       int progress = (int)
       ((float) copyedLength / fileLength * 100);
       handler.obtainMessage(0, progress, 0)。sendToTarget();
       }
       } catch (FileNotFoundException e) {
       e.printStackTrace();
       } catch (IOException e) {
       e.printStackTrace();
       } finally {
       handler.obtainMessage(1)。sendToTarget();
       }
       }
       }
       這一段是實(shí)現(xiàn)矩形繪圖的:
       private class DrawRunnable implements Runnable {
       @Override
       public void run() {
       try {
       while (true) {
       long beginTime = System.currentTimeMillis();
       paint.setColor(getColor());
       getCoor();
       postInvalidate();
       long endTime = System.currentTimeMillis();
       if (endTime - beginTime < 150) {
       Thread.sleep(150 - (endTime - beginTime));
       }
       }
       } catch (InterruptedException e) {
       e.printStackTrace();
       } finally {
       }
       }
       }
       實(shí)際上這兩種寫法都是利用了interrupt方法的特點(diǎn),通過線程的中斷置位或者異常拋出來跳出循環(huán)進(jìn)而終結(jié)線程。如果對(duì)這段代碼感興趣,可以到文章最后下載代碼。
       最后做一下方法總結(jié):
       void interrupt()
       向線程發(fā)送中斷請(qǐng)求。線程的中斷狀態(tài)將被設(shè)置為true.如果目前該線程被一個(gè)sleep調(diào)用阻塞,那么,InterruptedException異常被拋出。
       static boolean interrupted()
       測(cè)試當(dāng)前線程(即正在執(zhí)行這一命令的線程)是否被中斷,注意,這是一個(gè)靜態(tài)方法。這一調(diào)用會(huì)產(chǎn)生副作用,它將當(dāng)前線程的中斷狀態(tài)設(shè)置為false.
       boolean isInterrupted()
       測(cè)試線程是否被中斷。不像靜態(tài)的中斷方法,這一調(diào)用不會(huì)改變線程的中斷狀態(tài)。
       static Thread currentThread()
       返回代表當(dāng)前執(zhí)行線程的Thread對(duì)象。

    posted on 2013-11-21 17:54 好不容易 閱讀(153) 評(píng)論(0)  編輯  收藏


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    PK10開獎(jiǎng) PK10開獎(jiǎng)
    主站蜘蛛池模板: 99ee6热久久免费精品6| 国产免费卡一卡三卡乱码| 亚洲欧美日韩综合久久久久| 免费一看一级毛片人| 久久免费国产精品一区二区| 亚洲国产成人久久综合一区| 凹凸精品视频分类国产品免费| 国产精品玖玖美女张开腿让男人桶爽免费看 | 中文字幕 亚洲 有码 在线| 国产男女猛烈无遮挡免费视频网站 | 国产成人一区二区三区视频免费| 亚洲乱码一二三四区乱码| 中文字幕第一页亚洲| 成人免费大片免费观看网站| 特级毛片A级毛片免费播放| 久久久国产精品亚洲一区| 亚洲av午夜精品一区二区三区| 91av在线免费视频| 一进一出60分钟免费视频| 亚洲熟妇无码久久精品| 亚洲区不卡顿区在线观看| 91在线视频免费播放| 大地资源网高清在线观看免费 | 又大又硬又粗又黄的视频免费看| 亚洲国产精品久久网午夜| 亚洲综合伊人久久综合| 大学生美女毛片免费视频| 久久成人a毛片免费观看网站| 国产午夜亚洲精品不卡| 亚洲妓女综合网99| 亚洲精品乱码久久久久久蜜桃不卡| 最近2019中文字幕免费看最新| 亚洲视频在线观看免费| 一级白嫩美女毛片免费| 日本亚洲欧美色视频在线播放| 91亚洲国产成人久久精品| 亚洲αv久久久噜噜噜噜噜| 亚洲日韩VA无码中文字幕| 日本视频免费在线| 国产免费看JIZZ视频| 桃子视频在线观看高清免费视频|