ScheduledExecutorService ожидает завершения задачи. Накапливаются ли отложенные задачи, чтобы в конечном итоге прервать выполнение основной задачи? - PullRequest
0 голосов
/ 19 июня 2020

Мне было любопытно узнать о моей новой реализации с использованием ScheduledExecutorService, в которой ожидается, что задача завершится sh в течение периода 100 мс и задержки 0 мс. Но в случае, если есть нагрузка на систему и, скажем, 550 мс, будет ли очередь, поддерживаемая ScheduledExecutorService для тех, которые ожидают 4 задачи? И затем запустить, как только (задержка 0 мс) закончится первый. А что, если второе выполнение займет 560 мс, добавит ли это еще 4 потока в его очередь?

По этому поводу нет документации, или я мог бы это не заметить. Но я хочу убедиться, что скопление таких исполнений приведет к утечке или переполнению.

Например: приведенный ниже код может ли когда-нибудь выйти из строя основной поток?

    private static ScheduledExecutorService consumerThreadPool = Executors.newSingleThreadScheduledExecutor();
    public static void main(String[] args) throws Exception {
        consumerThreadPool.scheduleAtFixedRate(() -> performTask(), 0, 1, TimeUnit.MILLISECONDS);
    }

    private static void performTask () {
        try {
            Thread.sleep(550);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

1 Ответ

0 голосов
/ 20 июня 2020

Ваши задачи будут пропущены, если они будут переполнены в следующее запланированное время, вы можете легко проверить с помощью System.out.println и изменить время сна менее 500 мс на 5000 мс:

public static void main(final String[] args) throws InterruptedException, ExecutionException
{
    var executor = Executors.newScheduledThreadPool(1);
    var count = new AtomicInteger();

    Runnable task = () -> {
        String desc = "run("+((System.currentTimeMillis() / 1000) % 60)+") "+Thread.currentThread().getName()+" count "+count.incrementAndGet();
        System.out.println(desc);
        if(count.get() == 50)
            throw new RuntimeException("I give up!");

        try
        {
            Thread.sleep(2500);
        }
        catch (InterruptedException e)
        {
            System.out.println("Thread "+Thread.currentThread().getName()+" INTERRUPTED");
        }
    };
    var future = executor.scheduleAtFixedRate(task, 5000, 1000, TimeUnit.MILLISECONDS);

    System.out.println("Calling future.get() ...");
    try {
        var res = future.get();
        System.out.println("future.get()="+res);
    }
    catch(Exception e)
    {
        System.err.println("There was an exception:" +e);
        // Decide between "continue" or "throw e" here
        // ...
    }
    executor.shutdownNow();
    System.out.println("shutdown complete");
}
...