如何在 Thread.sleep 之后和之后调用一些代码

How to invoke some code once after and additional to a Thread.sleep

想象一下 运行在一个线程中使用此代码:

while (blockingQueue.size() > 0) {
    
    AbortableCountDownLatch latch = (AbortableCountDownLatch) blockingQueue.poll();
    latch.countDown();
}
Thread.sleep(updateinterval * 1000);

如何让while循环运行在Thread.sleep之后追加执行?比如:

Thread.sleepAndExecute(Runnable code, sleep time);

这样代码才执行,进入sleep之后,不是反过来吗?

blockingQueue 包含一些 CountDownLatch,它们正在阻塞另一个线程。如果闩锁全部倒计时并且该线程已进入 sleep/await 状态,则允许另一个线程继续。两个条件都必须为真,才能允许另一个线程继续。

您可能希望使用 CompletableFuturethenApply 方法作为对 supplyAsync.

的回调

顾名思义,supplyAsync 接受一个 Supplier<T> 作为参数,而 thenApply 接受一个 Function<T,R>:

CompletableFuture<String> futureText = CompletableFuture.supplyAsync(() -> {
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
       throw new IllegalStateException(e);
    }
    return "waited one second";
}).thenApply(input-> {
    // run some code as an additional execution
    return "inside thenApply, " + input;
});

System.out.println(futureText.get()); // prints: inside thenApply, waited one second

您需要在不同的线程中添加睡眠。您可以使用 completablefuture 或 Executorservice。

        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit( () -> {
            try {
                Thread.sleep(1000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        while (blockingQueue.size() > 0) {

            AbortableCountDownLatch latch = blockingQueue.poll();
            latch.countDown();
        }
        executorService.shutdown();

关键是你不应该需要睡觉。您可以使用 CompleteableFurture API thenCombine 来合并这两个任务。下面的代码

        CompletableFuture.runAsync(() -> {
            while (blockingQueue.size() > 0) {
                try {
                   System.out.println("Sleeping in thread - " + Thread.currentThread().getName());
                   Thread.sleep(1000l);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        })
        .thenCombine( CompletableFuture.runAsync( () -> {
            System.out.println("Polling in thread - " + Thread.currentThread().getName());
            while (blockingQueue.size() > 0) {

                AbortableCountDownLatch latch = blockingQueue.poll();
                latch.countDown();
            }
        }), (i, j) -> null);

睡眠和闩锁都发生在不同的线程中。

Sleeping in thread - ForkJoinPool.commonPool-worker-19
Polling in thread - ForkJoinPool.commonPool-worker-5
Sleeping in thread - ForkJoinPool.commonPool-worker-19

CompletionStages 在使用 *Async API 链接的两个阶段的帮助下实现 producer-consumer 并通过阻塞队列传递执行程序。我认为这应该最适合您的用例。