gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 02:47:56 27 4
gpt4 key购买 nike

在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

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

最佳答案

tl;dr

is there a way to check if Runnable is completed in single thread?

是的。

  1. 使用通过调用 Executors.newSingleThreadScheduledExecutor 提供的 ScheduledExecutorService 运行您的 Runnable
  2. 捕获返回的 ScheduledFuture 对象。
  3. 询问 ScheduledFuture 对象的完成状态,询问它是已完成还是已取消。

执行者框架

现代 Java 提供了 Executors 框架来很好地管理将任务分拆到其他线程上。参见 tutorial by Oracle .

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

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

ScheduledExecutorService scheduledExecutorService = … 

您要求单线程执行。这意味着你想要一个由 thread pool 支持的执行者大小为单个线程而不是多个。

ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor() ;

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

如果今天编写执行器框架,则延迟将表示为 java.time.Duration 对象。但是 java.time 还没有发明。因此,延迟表示为一些数字以及 TimeUnit。对象来指定时间的粒度。您没有指定所需的粒度,所以我会用几秒钟。

scheduledExecutorService.schedule( runnable , 10 , TimeUnit.SECONDS ); 

把所有这些放在一起。

Runnable runnable = ( ) -> {
System.out.println( "Running the runnable at " + Instant.now() );
};

ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.schedule( runnable , 10 , TimeUnit.SECONDS ); // Wait ten seconds before running the runnable.

// Wait long enough on this `main` thread for the background thread to do its thing.
try
{
Thread.sleep( Duration.ofSeconds( 12 ).toMillis() );
}
catch ( InterruptedException e )
{
e.printStackTrace();
}

// Clean-up.
scheduledExecutorService.shutdown(); // Always shutdown your executor service when no longer needed, or when ending your app.
System.out.println( "Done at " + Instant.now() );

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

查看此 code run live at IdeOne.com .

Running the runnable at 2020-11-16T05:30:04.106661Z
Done at 2020-11-16T05:30:06.105624Z

检查是否完成

你问:

Is there a way that I can check if the task1 has completed

是的。

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

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

Runnable runnable = ( ) -> {
System.out.println( "Running the runnable at " + Instant.now() );
};

ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture future = scheduledExecutorService.schedule( runnable , 10 , TimeUnit.SECONDS ); // Wait ten seconds before running the runnable.

try
{
Thread.sleep( Duration.ofSeconds( 4 ).toMillis() ); // Wait a short while, then see if runnable completed.
System.out.println( "isDone: " + future.isDone() + " | " + "isCancelled: " + future.isCancelled() );
Thread.sleep( Duration.ofSeconds( 4 ).toMillis() ); // Wait a short while, then see if runnable completed.
System.out.println( "isDone: " + future.isDone() + " | " + "isCancelled: " + future.isCancelled() );
Thread.sleep( Duration.ofSeconds( 4 ).toMillis() ); // Wait a short while, then see if runnable completed.
System.out.println( "isDone: " + future.isDone() + " | " + "isCancelled: " + future.isCancelled() );
}
catch ( InterruptedException e )
{
e.printStackTrace();
}

// Clean-up.
scheduledExecutorService.shutdown();
System.out.println( "Done at " + Instant.now() );

运行时。

isDone: false | isCancelled: false
isDone: false | isCancelled: false
Running the runnable at 2020-11-16T05:44:07.803125Z
isDone: true | isCancelled: false
Done at 2020-11-16T05:44:09.821267Z

关于java - 在Java中,有没有办法检查Runnable是否在单线程中完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64696406/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com