Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中如何无限期地等待?_Java_Multithreading - Fatal编程技术网

在Java中如何无限期地等待?

在Java中如何无限期地等待?,java,multithreading,Java,Multithreading,我有一个应用程序,它依赖于定时器和调度,而它的主要方法在执行应用程序设置后什么都不做 我看到这个成语用得很多: publicstaticvoidmain(最终字符串[]args){ //安排所有任务 while(true){ 试一试{ Thread.sleep(整数.MAX_值); }捕获(忽略最终中断异常){ Thread.interrupted(); } } } 有没有更好的方法写这个?出于某种原因,我真的需要这个而循环吗?(这似乎与Thread.interrupted()有关) 将一直休

我有一个应用程序,它依赖于
定时器
和调度,而它的主要方法在执行应用程序设置后什么都不做

我看到这个成语用得很多:

publicstaticvoidmain(最终字符串[]args){
//安排所有任务
while(true){
试一试{
Thread.sleep(整数.MAX_值);
}捕获(忽略最终中断异常){
Thread.interrupted();
}
}
}
有没有更好的方法写这个?出于某种原因,我真的需要这个
循环吗?(这似乎与
Thread.interrupted()
有关)

将一直休眠,直到JVM被杀死

请参阅以获取解释

将一直休眠,直到JVM被杀死

有关说明,请参阅。

tl;博士 不要自己管理线程

使用Executors框架创建一对executor服务

  • 一个executor服务可以执行任何请求的任务
  • 另一个定时执行器服务可以无限期地重复检查传入请求,在检查之间停留指定的时间以释放CPU核心。当找到请求时,此执行器服务会安排一个
    Runnable
    Callable
    在另一个执行器服务上执行
执行者框架 有更好的说法吗

是的,有更好的办法

使用Executors框架。见甲骨文

这个框架的发明是为了让我们不必直接管理线程。大多数情况都可以由Executors框架处理,只有极少数情况需要程序员处理线程

Executors框架取代了
Timer
&
TimerTask
类。如Javadoc类中所述:

Java 5.0引入了Java.util.concurrent包,其中一个并发实用程序是ScheduledThreadPoolExecutor,它是一个线程池,用于以给定的速率或延迟重复执行任务。它实际上是计时器/TimerTask组合的更通用的替代品,因为它允许多个服务线程,接受各种时间单位,并且不需要子类化TimerTask(只需实现Runnable)。将ScheduledThreadPoolExecutor配置为一个线程使其等效于计时器

我假设您尝试做的是偶尔发现需要完成的任务,然后在后台线程上执行该任务

为此,我们需要两个executor服务,每个服务都由一个线程池支持

  • 我们需要继续执行我们发现随着时间推移需要完成的任务。为此,我们使用一个无界线程池via。我们称之为我们的
    workers
    executor服务。如果您有CPU密集型任务,则可能需要由配置为最大线程数的线程池支持的替代执行器服务
  • 我们需要一个能够被告知每隔一段时间、不间断地重复一项或多项任务的系统。我们在这里要分配一个任务,该任务用于查找传入请求对其他executor服务上要调度的其他任务的影响。您没有在问题中解释,但我想象您正在检查队列、数据库、电子邮件或文件的存在,以获取要运行的新作业列表。检查工作是您在此作为此计划执行器服务的重复任务所做的。此executor服务在其池中只需要一个线程,由于缺少更好的名称,因此名为
    dispatcher
下面是一个版本的代码,模拟每次检查时,我们碰巧发现只需要完成一个任务。我们使用一个随机数来模拟一些被请求的任意任务。为了保持代码整洁,我们使用Java14中的新特性。交换机中的每个案例都会生成一个对象,并将该可运行对象提交给executor服务。executor服务在每个runnable提交时立即执行
run
方法。生成匿名
Runnable
对象的代码部分是以下lambda语法:

()->System.out.println(“Running Fruit report.Now:+Instant.Now())
您也可以使用常规语法来生成
Runnable
。您可能需要定义单独的类,这些类定义了任务代码所在的
Runnable

公共类报告实现可运行
{
公开募捐{
System.out.println(“Running Fruit report.Now:+Instant.Now());
}
}
完整的示例代码

package work.basil.example;
导入java.time.Instant;
导入java.util.concurrent.*;
公共类TimerTaskManager
{
服务人员;
ScheduledExecutorService调度器;
私有无效启动()
{
System.out.println(“INFO-Method`launch`running at”+Instant.now());
this.workers=Executors.newCachedThreadPool();
this.dispatcher=Executors.newSingleThreadScheduledExecutor();
this.dispatcher.scheduleWithFixedDelay(
( ) -> {
//检查是否有任何提示要执行任务的输入。
//我们使用随机数生成器来模拟到达的任意工作请求。
//使用Java14中的新开关表达式特性。https://openjdk.java.net/jeps/361
int r=ThreadLocalRandom.current().nextInt(1,6);//包含到独占。
开关(r)
{
案例1->this.workers.submit(()->System.out.println(“Running Fruit report.Now:+Instant.Now());//将匿名的'Runnable'对象传递给'ExecutorService::submit'方法。
案例2->this.workers.submit(()->System.out.println(“Running Wine report.Now:+Instant.Now());
Thread.currentThread().join();