2014-07-02 206 views
2

我們需要實現一項功能,允許我們取消未來的工作。鑑於這項工作正在進行數據庫調用,並且我們需要回滾\清除取消之前發生的任何更新。取消異步呼叫

這是我已經盡力了,但 「Thread.currentThread()isInterrupted()。」 總是返回false:

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); 
final Future future = executor.submit(new Callable() { 
    @Override 
    public Boolean call() throws Exception { 

    // Do Some DB calls 

    if (Thread.currentThread().isInterrupted()) { 
    // Will need to roll back   
     throw new InterruptedException(); 
    } 
    return true; 
    } 
}); 

executor.schedule(new Runnable() { 
    public void run() { 
    future.cancel(true); 
    } 
}, 1, TimeUnit.SECONDS); 

這是實現我們的目標是正確的做法?以及如何知道該作業是否被取消以取消\回滾更改?

+0

您確定取消任務在數據庫作業完成之前已經運行嗎? –

+0

其中一些調用可能需要很長時間才能完成,在這種情況下,線程停留在阻止其他作業啓動的池中。我們希望使用戶能夠取消整個工作,如果它花費了太多時間 – Transient

回答

1

首先看來線程池並沒有爲你創建新的線程,所以你的取消任務只有在數據庫任務完成後纔會被調用。所以我改變了你的例子池大小爲2,它的工作。

+0

只有在睡覺時拋出'InterruptedException'。如果你不睡覺,那麼檢查標誌是正確的,因爲異常不會被拋出。瞭解爲什麼'Thread.stop()'不被推薦理解爲什麼任意語句不只是拋出異常的原因。 http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html –

+0

你是對的!將修改我的答案,並upvote你 –

+0

很高興我可以幫助:) –

1

我相信你在第二項任務有機會運行之前完成數據庫調用。如果只有一個執行程序,則有可能在第一個完成之前不安排第二個計劃任務的時間。下面的代碼段會被中斷:

import java.util.*; 
import java.util.concurrent.*; 

public class Main { 
    public static void main(String[] arg) { 
     ScheduledExecutorService runner = Executors.newScheduledThreadPool(2); 
     // If this is 1 then this will never be interrupted. 

     final Future f = runner.submit(new Callable<Boolean>() { 
      public Boolean call() throws Exception { 
       System.out.println("Calling"); 
       while (! Thread.currentThread().isInterrupted()) { 
        ; 
       } 
       System.out.println("Interrupted"); 
       return true; 
      } 
     }); 

     runner.schedule(new Runnable() { 
      public void run() { 
       System.out.println("Interrupting"); 
       f.cancel(true); 
      } 
     }, 1, TimeUnit.SECONDS); 
    } 
}