在Java中,有没有办法检查Runnable是否在单线程中完成?

pie*_*die 3 java multithreading single-threaded runnable

在Java中,我需要获取两个参数,Runnable和Delay,单位是毫秒,并且需要在延迟时间内运行Runnable。这需要在单线程中运行,如果使用不同的参数值调用该方法并且前一个任务尚未完成,则应将其保留在队列中。

public void runScheduledTask(Runnable task, long delay) {
   // ...
}

...

runScheduledTask(task1, 10); // at 00:00:00.000
runScheduledTask(task2, 10); // at 00:00:00.005
Run Code Online (Sandbox Code Playgroud)

当用task2调用该方法时,task1尚未开始/完成,因为有延迟10,因此task2应该存储在队列中。在这种情况下,有没有办法检查任务 1 是否已完成?由于这应该在当前线程中运行,所以我不知道可以使用哪些类或工具。

Bas*_*que 5

太长了;博士

\n
\n

有没有办法检查 Runnable 是否在单线程中完成?

\n
\n

是的。

\n
    \n
  1. 通过调用 提供的来Runnable运行您的.ScheduledExecutorServiceExecutors.newSingleThreadScheduledExecutor
  2. \n
  3. 捕获返回的ScheduledFuture对象。
  4. \n
  5. 询问该ScheduledFuture对象的完成状态,询问它是否已完成或已取消。
  6. \n
\n

执行者框架

\n

现代 Java 提供了 Executors 框架来很好地管理将任务分拆到其他线程上。请参阅Oracle 的教程

\n

该类Executors(名称为复数)具有用于生成ExecutorService对象的工厂方法。

\n

您想要延迟执行而不是立即执行。所以比意味着你想要一个ScheduledExecutorService.

\n
ScheduledExecutorService scheduledExecutorService = \xe2\x80\xa6 \n
Run Code Online (Sandbox Code Playgroud)\n

您要求单线程执行。这意味着您需要一个由大小为单个线程而不是多个线程的线程池支持的执行器。

\n
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor() ;\n
Run Code Online (Sandbox Code Playgroud)\n

告诉预定的执行器服务在您想要的延迟后运行您的服务Runnable。调用 ScheduledExecutorService::schedule方法。

\n

如果今天编写执行程序框架,则延迟将表示为一个java.time.Duration对象。但当时java.time还没有发明。因此,延迟被表示为某个数字以及一个TimeUnit指定时间粒度的对象。您没有指定所需的粒度,因此我将选择秒。

\n
ScheduledExecutorService scheduledExecutorService = \xe2\x80\xa6 \n
Run Code Online (Sandbox Code Playgroud)\n

把所有这些放在一起。

\n
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor() ;\n
Run Code Online (Sandbox Code Playgroud)\n

请注意我们如何优雅地关闭执行程序服务。否则,在我们的应用程序结束后,支持执行器的线程可能会像僵尸一样无限期地继续运行。

\n

请参阅在 IdeOne.com 上实时运行的代码

\n
scheduledExecutorService.schedule( runnable , 10 , TimeUnit.SECONDS ); \n
Run Code Online (Sandbox Code Playgroud)\n

检查是否完成

\n

你问:

\n
\n

有没有办法检查task1是否已完成

\n
\n

是的。

\n

上面看到的方法ScheduledExecutorService::schedule返回一个ScheduledFuture对象。我们可以询问返回的ScheduledFuture对象的完成状态。

\n

我们上面的代码忽略了返回的对象。让我们更改代码来捕获返回的对象。

\n
Runnable runnable = ( ) -> {\n    System.out.println( "Running the runnable at " + Instant.now() );\n};\n\nScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();\nscheduledExecutorService.schedule( runnable , 10 , TimeUnit.SECONDS ); // Wait ten seconds before running the runnable.\n\n// Wait long enough on this `main` thread for the background thread to do its thing.\ntry\n{\n    Thread.sleep( Duration.ofSeconds( 12 ).toMillis() ); \n}\ncatch ( InterruptedException e )\n{\n    e.printStackTrace();\n}\n\n// Clean-up.\nscheduledExecutorService.shutdown();  // Always shutdown your executor service when no longer needed, or when ending your app.\nSystem.out.println( "Done at " + Instant.now() );\n
Run Code Online (Sandbox Code Playgroud)\n

运行时。

\n
Running the runnable at 2020-11-16T05:30:04.106661Z\nDone at 2020-11-16T05:30:06.105624Z\n
Run Code Online (Sandbox Code Playgroud)\n