android 如何結束一個線程?


  如何結束一個線程?html

 

關於線程的結束有如下幾點:java

1.不要手動調用stop方法強行終止一個線程,這種方式不安全。android

經過幫助文檔,咱們能夠知道,Android的線程類自己就提供一些公共方法去結束線程api

final void  stop()安全

This method is deprecated. because stopping a thread in this manner is unsafe and can leave your application and the VM in an unpredictable stateapp

 可是,經過說明咱們能夠看到,這些方法Android自己都是不推薦使用的,經過這種方式結束線程是不安全的。異步

2.線程裏run函數短,執行完後線程會自行銷燬,不用手動去終止。ide

3.手動中止,經過在run裏設置標誌先中止運行,再調用Thread.interrupt();注意,在run沒有中止時調用.interrupt()沒有效果。函數

android中關閉線程的的三種方法教程詳解
性能

1. 本身加入一個成員變量, 咱們在程序的循環裏面, 輪流的去檢查這個變量,  變量變化時,就會退出這個線程. 代碼示例以下


  1. package  com.test;

  2. public class StopThread extends  Thread {

  3.     private boolean  _run  = true;
  4.     public void stopThread( boolean  run) {
  5.          this ._run = !run;
  6.     }
  7.     
  8.     @Override
  9.    public void  run() {
  10.         while(_run) {
  11.            
  12.           //[img]http://www.blogjava.net/Images/dot.gif[/img]數據處理
  13.          
複製代碼
2. 方法1 雖然能夠能夠處理好, 不過, 在有阻塞線程的語句的時候每每不能處理好. 好比, 設計到Socket的阻塞語句. 雖然java有提供異步io可是異步io是在程序裏不斷去查詢有沒有消息的, 因此耗電量可想而知, 對手機這種設備來講每每不適用.

那麼阻塞的語句,怎麼終止線程呢?

Java雖然deprecate了一個stop,可是,提供了interrupt(),這個方法是安全的.  這個中斷方法能夠將阻塞的線程喚醒過來, 可是注意 他不能將非阻塞的線程中斷. 中斷的同時,會拋出一個異常InterruptedException. 幸運的是, SocketChannel.connect() .read() 阻塞方法都會接受中斷,ClosedByInterruptException.

這時咱們不輪詢變量了, 輪詢當前線程是否被中斷, 代碼

  1.             System.out.println("start");
  2.            while(!this.isInterrupted()) {
  3.                 [img]http://www.blogjava.net/Images/dot.gif[/img]數據處理
  4.              
  5.                      
  6. }
  7.         }catch (Exception e) {
  8.             e.printStackTrace();
  9.         }
  10.         System.out.println(stop);
  11.        super.run();
  12.    }

  13.     public static void main(String[] args) {
  14.         StopThread thread=new StopThread();
  15.         thread.start();
  16.        try {
  17.             Thread.sleep(1000);
  18.         }catch (InterruptedException e) {
  19.             e.printStackTrace();
  20.         }
  21.         
  22.         thread.interrupt();
  23.         System.out.println(interrupt);
  24.     }
  25. }
複製代碼
3. Android 在本身的Api中加入了,Process類, 這個類能夠直接終結進程, 也就是當前線程所在的JVM. 
final static void killProcess(int pid)  其中,pid, 能夠經過Process.mypid() 獲取, 但這樣終結的是整個程序, 不是咱們所想要的.

==================================================分割線==========================================

若是該線程處在不可中斷狀態下,就是沒有調用上述api,那麼java只是設置一下該線程的interrupt狀態,其餘事情都不會發生,若是該線程以後會調用行數阻塞API,那到時候線程會馬會上跳出,並拋出InterruptedException,接下來的事情就跟第一種情況一致了。若是不會調用阻塞 API,那麼這個線程就會一直執行下去。除非你就是要實現這樣的線程,通常高性能的代碼中確定會有wait(),yield()之類出讓cpu的函數,不會發生後者的狀況。

  1. readCacheThread = new Thread(){
  2.                 public void run() {
  3.                     
  4.                     try {
  5.                         Method getPackageSizeInfo = pm.getClass().getMethod(
  6.                                 "getPackageSizeInfo", String.class,
  7.                                 IPackageStatsObserver.class);
  8.                         for (AppInfoItem item : installedApp) {//我的應用
  9.                             sleep(1);//interrupt後會拋異常,這樣就能夠提早結束線程
  10.                             getPackageSizeInfo.invoke(pm, item.packageName, pkgsizeobserver);
  11.                         }
  12.                         for (AppInfoItem item : systemApp) {//系統應用
  13.                             sleep(1);
  14.                             getPackageSizeInfo.invoke(pm, item.packageName, pkgsizeobserver);
  15.                         }
  16.                         
  17.                     } catch (Exception e) {
  18.                         // TODO: handle exception
  19.                         e.printStackTrace();
  20.                         Log.e("qqqqqqqqqqqqq", "sleep over");
  21.                         return;
  22.                     }
  23.                     
  24.                 };
  25.             };
  26.             readCacheThread.start();
複製代碼
在須要中斷線程的地方調用:

  1. if(readCacheThread != null && readCacheThread.isAlive()){
  2.                 //Log.e("readCacheThread", "thread interrupt_1");
  3.                 readCacheThread.interrupt();
  4.                 //Log.e("status", ""+readCacheThread.isInterrupted());
  5.             }
複製代碼
(用判斷readCacheThread.isInterrupted()方法會失敗,由於總是返回false,不知道爲何。因此只能用sleep()而後捕獲異常再退出)。
這樣即可提早退出一個線程。
相關文章
相關標籤/搜索