2011-12-14 47 views
59

我想知道哪些是阻止Android中線程的最佳方式。我知道我可以使用AsyncTask代替它,並且有cancel()方法。我必須在我的情況下使用線程。下面是我如何使用線程:android最好和最安全的方式來停止線程

Runnable runnable = new Runnable() { 
     @Override 
     public void run() { 
      //doing some work 
     } 
    }; 
new Thread(runnable).start(); 

因此,任何人有任何想法,這是停止線程的最佳方式?

回答

13

Thread.stop()方法,其可用於停止一個線程已被棄用;更多信息請參閱; Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?

你最好的選擇是有其線程本身協商的變量,並自願當變量等於某個值退出。然後,當您希望線程退出時,您可以在代碼中操作變量。或者,當然,您也可以使用AsyncTask

+4

AsyncTask並不是中斷機制的替代品,它更像是一種與UI交互的工具。正如我在回答中指出的那樣,如果您希望在執行期間能夠停止它,您仍然必須在AsyncTask中實現與任何公共線程相同的機制。 – Malcolm 2011-12-14 14:45:15

58

你應該讓你的線程支持中斷。基本上,您可以撥打yourThread.interrupt()來停止線程,並且在您的run()方法中,您需要定期檢查Thread.interrupted()的狀態

有一個很好的教程here

+0

謝謝,我一直在尋找cancel()或stop()。 – 2016-02-17 09:38:43

+0

看起來乾淨,工作可靠。很好的答案,謝謝。 – 2017-06-15 20:19:51

24

這種情況不是從標準的Java不同的任何方式。您可以使用標準方式來停止線程:

class WorkerThread extends Thread { 
    volatile boolean running = true; 

    public void run() { 
     // Do work... 
     if (!running) return; 
     //Continue doing the work 
    } 
} 

主要想法是不時檢查字段的值。當您需要停止線程時,將running設置爲false。另外,正如克里斯指出的那樣,你可以使用中斷機制。

順便說一句,當您使用的AsyncTask,您apporach不會相差太多。唯一的區別是您必須從您的任務中調用isCancel()方法,而不是使用特殊字段。如果你打電話給cancel(true),但是不執行這個機制,線程仍然不會自行停止,它會運行到最後。

2

目前,不幸的是,我們不能做任何事情來阻止線程....

添加東西,馬特的答案,我們可以稱之爲interrupt(),但是這並不能阻止線程...只是告訴系統停止系統想要殺死一些線程時的線程。休息是由系統完成的,我們可以通過致電interrupted()進行檢查。

[p.s. :如果你真的與interrupt()去我要問你叫interrupt()]

-1

裏面你創建將分配NULL線程實例,它可以作爲一種方法的任何活動類後,做一些實驗,用很短的睡眠替代停止線程執行折舊stop()方法:

public class MyActivity extends Activity { 

private Thread mThread; 

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 


     mThread = new Thread(){ 
     @Override 
     public void run(){ 
      // Perform thread commands... 
    for (int i=0; i < 5000; i++) 
    { 
     // do something... 
    } 

    // Call the stopThread() method. 
      stopThread(this); 
      } 
     }; 

    // Start the thread. 
     mThread.start(); 
} 

private synchronized void stopThread(Thread theThread) 
{ 
    if (theThread != null) 
    { 
     theThread = null; 
    } 
} 
} 

這個工作對我來說沒有問題。

+2

非常感謝!大約一年來,我一直在尋找這樣的解決方案,而且這是唯一的解決方案! – Pkmmte 2013-04-17 08:17:15

16

在Android上應用相同的規則作爲一個正常的Java環境。 Java線程不會被終止,但是線程的停止是以合作方式完成的。線程被要求終止,然後線程可以優雅地關閉。

通常一個volatile boolean字段用於該線程週期性地檢查,並且當它被設置爲相應的值終止。

不會使用boolean檢查線是否應終止。如果您使用volatile作爲現場修改,這將工作可靠,但如果你的代碼變得更加複雜,對於而是使用while環內的其他阻止方法,它可能發生,你的代碼將不是在所有或至少終止你可能需要更長的需要更長的時間

某些阻斷庫方法支持中斷。

每個線程都有已經是布爾標誌中斷狀態,你應該利用它。它可以這樣實現:

public void run() { 

    try { 
     while(!Thread.currentThread().isInterrupted()) { 
     // ... 
     } 
    } catch (InterruptedException consumed) 
     /* Allow thread to exit */ 
    } 

} 

public void cancel() { interrupt(); } 

源代碼取自Java Concurrency in Practice。由於cancel()方法是公開的,因此您可以讓另一個線程根據需要調用此方法。

還有一個名爲不佳靜態方法interrupted它清除當前線程的中斷狀態。

1

的事情是,你需要檢查線程運行或不?! 現場:

private boolean runningThread = false; 

在線程:

new Thread(new Runnable() { 
      @Override 
      public void run() { 
       while (true) { 
        try { 
         Thread.sleep((long) Math.floor(speed)); 
         if (!runningThread) { 
          return; 
         } 
         yourWork(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     }).start(); 

如果你想停止線程,你應該做以下領域

private boolean runningThread = false; 
1

有2種以下方式首選停止線。

  1. 創建一個易失性布爾變量並將其值更改爲false並檢查線程內部。

    volatile isRunning = false;

    公共無效的run(){ 如果(!isRunning){回報;}}

  2. 或者您可以使用它可以線程內部接收中斷()方法。

    SomeThread.interrupt();

    公共無效的run(){ 如果(Thread.currentThread.isInterrupted()){返回;}}

0

我使用該方法。

Looper.myLooper().quit(); 

你可以試試。

0

這對我這樣工作。在主要活動中引入一個靜態變量,並定期檢查它是如何做到的。

public class MainActivity extends AppCompatActivity { 


//This is the static variable introduced in main activity 
public static boolean stopThread =false; 



    protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    Thread thread = new Thread(new Thread1()); 
    thread.start(); 

    Button stp_thread= findViewById(R.id.button_stop); 

    stp_thread.setOnClickListener(new Button.OnClickListener(){ 
      @Override 
      public void onClick(View v){ 
       stopThread = true; 
      } 

    } 

    } 


    class Thread1 implements Runnable{ 

     public void run() { 

     // YOU CAN DO IT ON BELOW WAY 
     while(!MainActivity.stopThread) { 
      Do Something here 
     } 


     //OR YOU CAN CALL RETURN AFTER EVERY LINE LIKE BELOW 

     process 1 goes here; 

     //Below method also could be used 
     if(stopThread==true){ 
      return ; 
     } 
     // use this after every line 



     process 2 goes here; 


     //Below method also could be used 
     if(stopThread==true){ 
      return ; 
     } 
     // use this after every line 


     process 3 goes here; 


     //Below method also could be used 
     if(stopThread==true){ 
      return ; 
     } 
     // use this after every line 


     process 4 goes here; 



     } 
    } 

} 
相關問題