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

如何在Java中无限期等待?

隗星驰
2023-03-14
public static void main(final String[] args) {
    // schedule all tasks
    while (true) {
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (final InterruptedException ignored) {
            Thread.interrupted();
        }
    }
}

有没有更好的写法呢?由于某种原因,我真的需要这个while循环吗?(似乎与线程.中断()有关)

共有1个答案

黄宏大
2023-03-14

不要自己管理线程。

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

  • 一个执行器服务可以执行任何请求的任务。
  • 另一个调度的执行器服务可以无限期地重复检查传入请求,在检查之间Rest一段指定的时间,以释放CPU内核。找到请求后,此executor服务将调度一个runnablecallable在另一个executor服务上执行。
  • 我们需要executor服务来执行随着时间的推移发现需要完成的任务。为此,我们通过executors.newCachedThreadPool使用无界线程池。我们称之为workers执行器服务。如果您有CPU密集型任务,则可能需要由配置为最大线程数的线程池支持的替代执行器服务。
  • 我们需要一个调度的执行器服务,它可以被告知每隔一段时间重复一个或多个任务,并且无限期地重复。我们在这里分配了一个任务,该任务查找传入请求的内容,以便在另一个executor服务上调度其他任务。您没有在问题中解释,但我想您正在检查队列、数据库、电子邮件或文件的存在,以获得要运行的新作业列表。检查工作是您在此执行器服务上作为重复任务所做的工作。此执行器服务在其池中只需要一个线程,由于没有更好的名称,因此命名为dispatcher

这里是代码的一个版本,它模拟了每次检查时只需要完成一个任务的情况。我们使用一个随机数来模拟某个被请求的任意任务。为了保持代码的整洁,我们使用了Java14中新的开关表达式特性。交换机中的每个案例都生成一个runnable对象,并将该runnable对象提交给executor服务。executor服务在提交时到达每个runnable时立即执行run方法。生成匿名runnable对象的代码部分是以下lambda语法:

( ) -> System.out.println( "Running Fruit report. Now: " + Instant.now() )

您也可以使用常规语法生成runnable。您很可能希望定义单独的类,这些类定义runnable并将任务代码放置在其中。

public class FruitReport implements Runnable
{
    public void run() {
        System.out.println( "Running Fruit report. Now: " + Instant.now() ) ;
    }
}
package work.basil.example;

import java.time.Instant;
import java.util.concurrent.*;

public class TimerTaskManager
{
    ExecutorService workers;
    ScheduledExecutorService dispatcher;


    private void launch ( )
    {
        System.out.println( "INFO - Method `launch` running at " + Instant.now() );
        this.workers = Executors.newCachedThreadPool();
        this.dispatcher = Executors.newSingleThreadScheduledExecutor();
        this.dispatcher.scheduleWithFixedDelay(
                ( ) -> {
                    // Check for whatever input you have that prompts for tasks to be performed.
                    // We use a random number generator to simulate arbitrary work requests arriving.
                    // Using the new switch expressions feature in Java 14. https://openjdk.java.net/jeps/361
                    int r = ThreadLocalRandom.current().nextInt( 1 , 6 ); // inclusive-to-exclusive.
                    switch ( r )
                    {
                        case 1 -> this.workers.submit( ( ) -> System.out.println( "Running Fruit report. Now: " + Instant.now() ) );  // Passing an anonymous `Runnable` object to the `ExecutorService::submit` method. 
                        case 2 -> this.workers.submit( ( ) -> System.out.println( "Running Wine report. Now: " + Instant.now() ) );
                        case 3 -> this.workers.submit( ( ) -> System.out.println( "Running Clothing report. Now: " + Instant.now() ) );
                        case 4 -> this.workers.submit( ( ) -> System.out.println( "Running Appliance report. Now: " + Instant.now() ) );
                        case 5 -> this.workers.submit( ( ) -> System.out.println( "Running Tools report. Now: " + Instant.now() ) );
                        default -> System.out.println( "ERROR - Unexpected r value: " + r );
                    }
                } ,
                3 ,
                10 ,
                TimeUnit.SECONDS
        );
    }

    private void shutdown ( )
    {
        this.dispatcher.shutdown();
        this.workers.shutdown();
        System.out.println( "INFO - Method `shutdown` running at " + Instant.now() );
    }

    public static void main ( String[] args )
    {
        TimerTaskManager app = new TimerTaskManager();
        app.launch();

        try
        {
            Thread.sleep( TimeUnit.MINUTES.toMillis( 1 ) );
        }
        catch ( InterruptedException e )
        {
            e.printStackTrace();
        }
        finally
        {
            app.shutdown();
        }
    }
}
INFO - Method `launch` running at 2020-06-28T04:16:17.742443Z
Running Wine report. Now: 2020-06-28T04:16:20.786653Z
Running Tools report. Now: 2020-06-28T04:16:30.787891Z
Running Appliance report. Now: 2020-06-28T04:16:40.791585Z
Running Wine report. Now: 2020-06-28T04:16:50.796355Z
Running Fruit report. Now: 2020-06-28T04:17:00.800407Z
Running Appliance report. Now: 2020-06-28T04:17:10.805166Z
INFO - Method `shutdown` running at 2020-06-28T04:17:17.783938Z
package work.basil.example;

import java.time.Instant;
import java.util.concurrent.*;

public class TimerTaskManager
{
    ExecutorService workers;
    ScheduledExecutorService dispatcher;


    private void launch ( )
    {
        System.out.println( "INFO - Method `launch` running at " + Instant.now() );
        this.workers = Executors.newCachedThreadPool();
        this.dispatcher = Executors.newSingleThreadScheduledExecutor();
        this.dispatcher.scheduleWithFixedDelay(
                ( ) -> {
                    // Check for whatever input you have that prompts for tasks to be performed.
                    int countRequests = ThreadLocalRandom.current().nextInt( 1 , 7 );
                    System.out.println( "INFO - Found " + countRequests + " incoming requests for work to be done. Now: " + Instant.now() );
                    for ( int i = 1 ; i <= countRequests ; i++ )
                    {
                        // We use a random number generator to simulate arbitrary work requests arriving.
                        // Using the new switch expressions feature in Java 14. https://openjdk.java.net/jeps/361
                        int r = ThreadLocalRandom.current().nextInt( 1 , 6 ); // inclusive-to-exclusive.
                        switch ( r )
                        {
                            case 1 -> this.workers.submit( ( ) -> System.out.println( "Running Fruit report. Now: " + Instant.now() ) );  // Passing an anonymous `Runnable` object to the `ExecutorService::submit` method. 
                            case 2 -> this.workers.submit( ( ) -> System.out.println( "Running Wine report. Now: " + Instant.now() ) );
                            case 3 -> this.workers.submit( ( ) -> System.out.println( "Running Clothing report. Now: " + Instant.now() ) );
                            case 4 -> this.workers.submit( ( ) -> System.out.println( "Running Appliance report. Now: " + Instant.now() ) );
                            case 5 -> this.workers.submit( ( ) -> System.out.println( "Running Tools report. Now: " + Instant.now() ) );
                            default -> System.out.println( "ERROR - Unexpected r value: " + r );
                        }
                    }
                } ,
                3 ,
                10 ,
                TimeUnit.SECONDS
        );
    }

    private void shutdown ( )
    {
        this.dispatcher.shutdown();
        this.workers.shutdown();
        System.out.println( "INFO - Method `shutdown` running at " + Instant.now() );
    }

    public static void main ( String[] args )
    {
        TimerTaskManager app = new TimerTaskManager();
        app.launch();

        try
        {
            Thread.sleep( TimeUnit.MINUTES.toMillis( 1 ) );
        }
        catch ( InterruptedException e )
        {
            e.printStackTrace();
        }
        finally
        {
            app.shutdown();
        }
    }
}
INFO - Method `launch` running at 2020-06-28T04:34:52.097616Z
INFO - Found 2 incoming requests for work to be done. Now: 2020-06-28T04:34:55.112823Z
Running Tools report. Now: 2020-06-28T04:34:55.122258Z
Running Appliance report. Now: 2020-06-28T04:34:55.122653Z
INFO - Found 2 incoming requests for work to be done. Now: 2020-06-28T04:35:05.127456Z
Running Appliance report. Now: 2020-06-28T04:35:05.128309Z
Running Clothing report. Now: 2020-06-28T04:35:05.128297Z
INFO - Found 5 incoming requests for work to be done. Now: 2020-06-28T04:35:15.128481Z
Running Tools report. Now: 2020-06-28T04:35:15.129414Z
Running Wine report. Now: 2020-06-28T04:35:15.129430Z
Running Appliance report. Now: 2020-06-28T04:35:15.129663Z
Running Tools report. Now: 2020-06-28T04:35:15.130001Z
Running Fruit report. Now: 2020-06-28T04:35:15.130441Z
INFO - Found 4 incoming requests for work to be done. Now: 2020-06-28T04:35:25.133727Z
Running Clothing report. Now: 2020-06-28T04:35:25.133880Z
Running Wine report. Now: 2020-06-28T04:35:25.133917Z
Running Wine report. Now: 2020-06-28T04:35:25.133967Z
Running Wine report. Now: 2020-06-28T04:35:25.134148Z
INFO - Found 6 incoming requests for work to be done. Now: 2020-06-28T04:35:35.136503Z
Running Tools report. Now: 2020-06-28T04:35:35.136663Z
Running Wine report. Now: 2020-06-28T04:35:35.136733Z
Running Clothing report. Now: 2020-06-28T04:35:35.136764Z
Running Clothing report. Now: 2020-06-28T04:35:35.136735Z
Running Appliance report. Now: 2020-06-28T04:35:35.137363Z
Running Clothing report. Now: 2020-06-28T04:35:35.137349Z
INFO - Found 3 incoming requests for work to be done. Now: 2020-06-28T04:35:45.136728Z
Running Appliance report. Now: 2020-06-28T04:35:45.136943Z
Running Clothing report. Now: 2020-06-28T04:35:45.136940Z
Running Tools report. Now: 2020-06-28T04:35:45.136948Z
INFO - Method `shutdown` running at 2020-06-28T04:35:52.111007Z
 类似资料:
  • 我有一段非基于演员的代码,它将一些操作委托给akka演员,我想无限期地等待这个演员的响应,我的意思是,直到这个演员返回一个响应,无论需要多长时间。问题是我不知道如何在未来无限期地等待attern.ask和wait.result方法。 我更喜欢这样的东西: 但这不起作用,因为Timeout不接受Duration对象作为构造函数参数,它只接受FiniteDuration对象。。。 任何想法? 干杯

  • 我实际上有三个问题: Selenium WebDriver如何实现此 因为我们不能给无限睡眠的线程一个负值。 有没有更好的方法来实现无限等待? 我们在SeleniumWebDriver文档中看到了这一点

  • 问题内容: 我最近开始尝试使用Python进行Web开发。到目前为止,我在将Apache与mod_wsgi结合使用以及针对python 2.7的Django Web框架方面取得了一些成功。但是,我遇到了一些问题,这些问题导致流程不断运行,更新信息等。 我编写了一个脚本,称为“ daemonManager.py”,该脚本可以启动和停止所有或单个python更新循环(我应该将它们称为Daemon吗?)

  • 问题内容: 我想要一个可以在后台运行直到停止的服务,即使启动该服务的组件已损坏并且也允许绑定到活动。怎么可能? 根据android绑定服务文档-有三种创建绑定服务的方法 扩展Binder类。 使用Messenger。 使用AIDL。 我已经使用Messenger(第二种方法)创建了绑定服务。活动通过其onStart()方法绑定到服务,并在其onStop()方法中取消绑定。两种消息传递方式(在活动和

  • 我有这样的代码: 我知道这不是做这件事的正确方法。以下是我认为可能是正确的方法: 不过,我只是想知道,为什么在运行第一个代码示例时,它会无限期地挂在上?此时代码执行到底发生了什么,即当线程在上阻塞时,什么代码“正在运行”?

  • 假设我有几个未来,需要等到它们中的任何一个失败或全部成功。 例如:设有3个期货:、、。 > 如果成功而失败,我不会等待(并将失败返回给客户端)。 如果<code>f2</code>失败,而<code>f1</code>和<code>f3</code>仍在运行,我不会等待它们(并返回故障) 如果成功,然后成功,我继续等待。 你将如何实现它?