Java 多线程 - 使用数据库和 http 连接取消 future 任务的更好方法?

标签 java multithreading future callable

我很难按照我希望的方式正确地对我的应用程序进行编程。

目前,我的应用程序(作为 Java Servlet)将查询数据库以获取要处理的项目列表。对于列表中的每个项目,它将提交一个 HTTP Post 请求。我正在尝试创建一种方法,如果用户请求,我可以停止此处理(甚至终止正在进行的 HTTP Post 请求)。可以存在分别处理不同查询的并发线程。现在,我将停止所有线程中的处理。

我当前的尝试涉及在 Callable 类中实现数据库查询和 HTTP Post。然后我通过 Executor Service 提交 Callable 类来获取 Future 对象。

但是,为了正确停止处理,我需要中止 HTTP Post 并关闭数据库的连接、语句和结果集 - 因为 Future.cancel() 不会为我执行此操作。当我对 Future 对象调用 cancel() 时,我该如何做到这一点?我是否必须存储包含 Future 对象、HttpPost、Connection、Statement 和 ResultSet 的数组列表?这似乎太过分了——肯定有更好的方法吗?

这是我现在拥有的一些代码,仅中止 HttpPost(而不是任何数据库对象)。

private static final ExecutorService pool = Executors.newFixedThreadPool(10);
public static Future<HttpClient> upload(final String url) {
    CallableTask ctask = new CallableTask();
    ctask.setFile(largeFile);
    ctask.setUrl(url);
    Future<HttpClient> f = pool.submit(ctask); //This will create an HttpPost that posts 'largefile' to the 'url'
    linklist.add(new tuple<Future<HttpClient>, HttpPost>(f, ctask.getPost())); //storing the objects for when I cancel later
    return f;
}


//This method cancels all running Future tasks and aborts any POSTs in progress
public static void cancelAll() {
    System.out.println("Checking status...");

    for (tuple<Future<HttpClient>, HttpPost> t : linklist) {
        Future<HttpClient> f = t.getFuture();
        HttpPost post = t.getPost();
        if (f.isDone()) {
            System.out.println("Task is done!");
        } else {
            if (f.isCancelled()) {
                System.out.println("Task was cancelled!");
            } else {
                while (!f.isDone()) {
                        f.cancel(true);
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("!Aborting Post!");
                        try {
                            post.abort();
                        } catch (Exception ex) {
                            System.out.println("Aborted Post, swallowing exception: ");
                            ex.printStackTrace();
                        }

                }
            }
        }
    }
}

有没有更简单的方法或者更好的设计?现在我终止所有处理线程 - 将来,我想终止单个线程。

最佳答案

我认为保留所有要关闭的资源的列表并不是最好的方法。在您当前的代码中,HTTP 请求似乎是由 CallableTask 发起的,但关闭是由其他人完成的。在我看来,关闭资源是打开资源的人的责任。

我会让 CallableTask 发起 HTTP 请求,连接到数据库并执行它的操作,当它完成或中止时,它应该关闭它打开的所有内容。这样,您只需跟踪代表当前正在运行的任务的 Future 实例。

关于Java 多线程 - 使用数据库和 http 连接取消 future 任务的更好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18475204/

相关文章:

java - ActiveMQ安装时出错

python - 如何通过知道线程 ID 来获取线程的名称?

c++ - 难以理解 * 和 & 当它们与线程一起出现时

java - 如何在Java中声明Callable来执行返回void的函数?

python - 组合像 Promise.all 这样的等待对象

java - 数组越界错误

java - Jackson根据接口(interface)序列化

Java 大整数

c# - 多线程BlockingCollection同值

java - 在 Completable Future 中从 lambda 抛出时未报告的异常