2017-02-03 33 views
1

我想在點擊按鈕上執行一些長時間運行的任務,如果用戶再次點擊該按鈕,當前任務強制停止並將執行下一個任務?如何強制停止線程並使用新變量啓動相同的線程?

+0

你是什麼樣的任務using..Thread,...的AsyncTask我 – Meenal

+1

使用線程 –

+0

@ BincyBaby我在我的答案中添加了一個純粹的基於java的解決方案。希望它會有所幫助。只有你需要關心我的解決方案是你不應該更新從主要gui線程以外的線程的GUI,如果你想要做的話,然後使用在主要gui線程中實例化的Handler。希望我的解決方案對你有所幫助。 –

回答

1

我發佈了一個純粹的基於Java的代碼,它也可以在android中工作。在使用android時只需要注意不要從程序的一部分更新GUI,而這部分程序會在主GUI線程以外的線程中執行。如果您希望從另一個線程編輯GUI,那麼您可以使用在主GUI線程中實例化的Handler。

定義基本接口,這樣的模型

/** 
* 
* @author nits.kk 
* 
* This defines the methods for the model. 
* 
*/ 
public interface IResumable { 
    /** 
    * starts the model 
    */ 
    public void requestStart(); 
    /** 
    * requests the model to pause 
    */ 
    public void requestPause(); 
    /** 
    * requests the model to resume with new parameter 
    * @param newParam 
    */ 
    public void resumeWithNewParam(int newParam); 
/** 
    * terminate the model 
    */ 
    public void requestStop(); 
} 

現在的具體實施

public class ResumableModel implements IResumable { 
    private Thread worker; 
    private WorkerRunnable work; 

    public ResumableModel(int initialValue) { 
     work = new WorkerRunnable(initialValue); 
     worker = new Thread(work); 
    } 

    @Override 
    public void requestStart() { 
     worker.start(); 
    } 

    @Override 
    public void requestPause() { 
     work.setPauseRequested(true); 
    } 

    @Override 
    public void resumeWithNewParam(int newParam) { 
     work.setNewParam(newParam); 
    } 

    @Override 
    public void requestStop() { 
     worker.interrupt(); 
    } 

    private static class WorkerRunnable implements Runnable { 
     private int param; // we can have the variable of the type depending upon the requirement. 
     private final Object lock = new Object(); 
     private volatile boolean isPauseRequested = false; 

     public void run() { 
       synchronized (lock) { 
        try { 
          while (!Thread.currentThread().isInterrupted()) { 
           while (isPauseRequested) { 
             lock.wait(); 
           } 
           System.out.println("value of param is" + param); 
          } 
        } catch (InterruptedException e) { 
          e.printStackTrace(); 
        } 
       } 
     } 

     public WorkerRunnable(int param) { 
       this.param = param; 
     } 

     private void setPauseRequested(boolean isPauseRequested) { 
       this.isPauseRequested = isPauseRequested; 
     } 

     private void setNewParam(int param) { 
       // double locking to prevent the calling thread from being locked 
       // (if in running state without pause requested then calling thread 
       // will be in indefinite wait state for acquiring the lock. 
       if (isPauseRequested) { 
        synchronized (lock) { 
          if (isPauseRequested) { 
           this.param = param; 
           this.isPauseRequested = false; 
           lock.notifyAll(); 
          } else { 
           // logger will be used in real application 
           System.out.println("Need to pause first before setting a new param"); 
          } 
        } 
       } else { 
        // logger will be used in real application 
        System.out.println("Need to pause first before setting a new param"); 
       } 
     } 
    } 
} 

現在,當你想開始你可以做以下

IResumable resumable = new ResumableModel(10); 
resumable.requestStart(); 

當線程你想暫停線程,你可以簡單地調用requestPause()方法

resumable.requestPause(); 

現在,當您需要使用新的變量值恢復線程時,您可以調用resumeWithNewParam

resumable.resumeWithNewParam(20); 

現在,當你覺得你不需要的線程和模式應該終止,那麼你可以調用resumable.requestStop();

0

您可以創建這樣

public class AsyncThread extends Thread{ 
     @Override 
     public void run() { 
      super.run(); 
      //do your task 
     } 
    } 

線程類,並檢查線程仍然活着

AsyncThread thread = new AsyncThread(); 
     if(thread.isAlive()){ 
      thread.interrupt(); 
      //do other stuff 
     }else{ 
      thread.start(); 
     } 
+0

它的工作原理,但不立即中斷+1 –

+0

不,這不是你想要的。它總是啓動一個**新線程**。 'thread.isAlive()'將始終返回'false'。 – mallaudin

+0

將'this.hashCode()'添加到'run()'方法,並看到它將始終打印一個唯一值。 – mallaudin

0

不能重新啓動一個線程,一旦它停止。

我建議使用Looper/Handler API將任務放入隊列中並讓處理程序在單獨的線程上執行它們。

我有圈套/處理程序hereexplanation的演示項目。看看你是否想這樣實現它。

另一個選項(如@Guna所提到的)是,您可以創建緩存的線程池並讓執行程序在線程上運行任務。

+0

我不想排隊任務,我只是想停止以前的任務,並開始新的 –

+0

在問題中解釋你到底想要達到什麼目的。你正在執行什麼樣的任務。 etc – mallaudin

+0

上午在線程內執行解密和文件創建,並將播放該解密的臨時文件,如果用戶點擊下一步想播放下一首歌曲 –

0

你必須在你的運行方法中檢查一個標誌。當您希望線程取消時,此標誌可以設置爲false。 下一次你的run方法檢查這個標誌,因爲它的false因此它退出線程。 可能你想使用ThreadPoolExecutor?