当前位置: 首页 > 知识库问答 >
问题:

检查线程是否关闭,并在关闭后执行任务

农鸿达
2023-03-14

我正在创建一个固定大小的线程池,包含10个线程,如下所示:

ExecutorService executorService = Executors.newFixedThreadPool(10);

for (int i = 0; i < poolSize; ++i) {
   executorService.execute(factory.get());
}

现在,在生成10个线程之后,每个线程都会执行一个runnable。这里的Runnable由工厂提供。得到()

现在,我想做一件事,一旦一个线程被关闭,也就是说,它完成了一个任务,它就会再次选择另一个runnable并开始运行它。因此,基本上检查所有10个线程的状态,并在线程关闭时再次执行runnable。

我知道我可以这样做,在其中我可以调用executorService shutdown()方法,如下所示:

   while (!executorService.isShutdown()) {
        try {
            executorService.execute(factory.get());
        } catch (RejectedExecutionException e) {
            if (!executorService.isShutdown())
                log.warn("task submission rejected");
        }
    }

但在这种方法中,问题是我一直在调用execute函数,这会增加LinkedBlockingQueue,不符合我的目的。

如果我能以某种方式检查线程状态,那将是件好事,因为这样可以避免返回执行器服务获取更多工作的开销。

请建议如何在代码中做到这一点。

共有2个答案

邢鸿博
2023-03-14

如果要连续运行10个线程,为什么要使用线程池?只需自己开始10个线程。

为什么在10个工作线程之上有一个“控制器”线程?让每个线程请求执行下一个任务。

以下假设工厂。get()是线程安全的。

for (int i = 0; i < 10; i++) {
    new Thread(() -> {
        for (;;) {
            Runnable r = factory.get(); // <-- must be thread-safe
            if (r == null)
                break; // stop thread if no more tasks to execute
            try {
                r.run();
            } catch (Exception e) {
                // log exception here
            }
        }
    }).start();
}

如果需要,将10个线程对象保存在一个数组中。

如果您希望能够在没有工厂的情况下关闭线程。get()返回null,添加一个volatile boolean,并在循环中检查它。

陶高峻
2023-03-14

您可以使用有界执行器。以下是jcip的Brian Goetz的代码

/**
 * BoundedExecutor
 * <p/>
 * Using a Semaphore to throttle task submission
 *
 * @author Brian Goetz and Tim Peierls
 */
public class BoundedExecutor {
    private final Executor exec;
    private final Semaphore semaphore;

    public BoundedExecutor(Executor exec, int bound) {
        this.exec = exec;
        this.semaphore = new Semaphore(bound);
    }

    public void submitTask(final Runnable command)
            throws InterruptedException {
        semaphore.acquire();
        try {
            exec.execute(new Runnable() {
                public void run() {
                    try {
                        command.run();
                    } finally {
                        semaphore.release();
                    }
                }
            });
        } catch (RejectedExecutionException e) {
            semaphore.release();
        }
    }
}

然后只需创建并使用它:

ExecutorService executorService = Executors.newFixedThreadPool(10);
BoundedExecutor boundedExecutor = new BoundedExecutor(executorService,10);

while (!executorService.isShutdown()) {
    try {
        boundedExecutor.submitTask(factory.get());
    } catch (InterruptedException e) {
    }
}       

这样,您将始终有10个线程在运行,新任务只会在旧任务完成后提交,您可以通过关闭执行程序来停止执行。

 类似资料:
  • 我有一个GLSURFACHEVIEW,在那里我呈现我的GUI。在一种情况下,我需要用户输入一个数字,为了实现这一点,我使用了一个框架布局,上面是我的GLSurfaceView,后面是另一个虚拟布局,后面是EditText。当需要输入时,我聚焦编辑文本并强制软键盘显示。然后我听各种方法来结束输入,输入键,输入法动作完成,返回键等等。 然而,我刚刚意识到一个情况,这是不起作用的。在某些键盘上有一个“隐

  • 我是Apache Flink的新手,所以我目前正在尝试做一些实验。我正在读Kafka的一个主题,然后在控制台上打印出来。打印大约100kkafka消息后,它抛出异常。日志输出如下。 我正在使用一个自定义类来扩展AbstractDeserializationSchema,以反序列化kafka记录值。我甚至尝试过在其中添加一些异常处理,但没有触发。 我使用Kafka的代码非常简单: 即使在异常之后,输

  • 问题内容: 我想知道,在关闭阅读器之后,是否需要关闭InputStream? 问题答案: 不,您不必。 由于Java中用于流的装饰器方法可以通过将新流或读取器附加到其他流上来构建新流或读取器,因此实现将自动对其进行处理。 如果查看其来源,则会看到: 因此,关闭操作实际上关闭了底层的流读取器。 编辑:我想确保关闭也可以在输入流上工作,请继续关注。 签入 在调用sd的close时调用。

  • 问题内容: 下面的代码尝试做到这一点。 该代码将永远循环并检查是否有任何待处理的请求要处理。如果存在,它将创建一个新线程来处理请求并将其提交给执行者。一旦所有线程完成,它将休眠60秒,然后再次检查未决请求。 我的问题是这些线程完成的大多数处理都是针对数据库的。该程序将在Windows计算机上运行。当有人尝试关闭或注销计算机时,这些线程会发生什么?如何正常关闭正在运行的线程以及执行程序? 问题答案:

  • 本文向大家介绍javascript在当前窗口关闭前检测窗口是否关闭,包括了javascript在当前窗口关闭前检测窗口是否关闭的使用技巧和注意事项,需要的朋友参考一下 在当前窗口关闭前,检测当前窗口是否关闭 在ie9中,如果刷新文档的话,unloadform和onbeforeunload都会执行,如果是关闭页面的话只会执行onbeforeunload事件 值得注意的是,onunload在关闭页面时

  • 问题内容: 这是我的代码段。 现在做完之后 我要在这里实现的是,我要等待线程池中的所有线程完成执行,然后关闭执行器。 但是我想这不是这里正在发生的事情。主线程似乎正在执行关闭,它只是关闭了所有内容。 在我的线程池大小为2之前,我做了以下事情,而且似乎可行。 我如何在线程池中使用更多线程?谢谢。 问题答案: 您通常使用以下成语: 只是说执行者不会接受新工作。 等待直到所有已提交的任务完成它们的工作(