取消异步调用

时间:2014-07-02 10:41:04

标签: java multithreading future

我们需要实现一项允许我们取消未来工作的功能。鉴于此作业正在执行数据库调用,我们需要回滚\ cleanup在取消触发之前所做的任何更新。

这是我尝试过的,但" 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);

这是实现目标的正确方法吗?如何知道作业是否被取消以取消\回滚更改?

2 个答案:

答案 0 :(得分:1)

首先,似乎线程池没有为您创建新线程,因此只有在DB任务完成后才会调用取消任务。所以我将你的示例中的池大小更改为2并且它有效。

答案 1 :(得分: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);
    }
}