管理多线程永动任务

涉及概念:

  1. 线程池:使用ExecutorServiceScheduledExecutorService来管理线程,避免手动创建和管理线程。
  2. Future 和 CompletableFuture:用于获取异步任务的结果或处理异步任务的完成。
  3. 优雅关闭:确保在应用程序关闭时能够正确关闭线程池和取消未完成的任务。

示例:

ScheduledExecutorService

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class PerpetualAsyncTask {
    private final ScheduledExecutorService executorService;
    private final ScheduledFuture<?> scheduledFuture;

    public PerpetualAsyncTask() {
        // 创建一个单线程的ScheduledExecutorService
        executorService = Executors.newSingleThreadScheduledExecutor();

        // 提交一个永动任务
        Runnable task = () -> {
            // 这里是你的任务逻辑
            System.out.println("Task is running...");
        };

        // 初始延迟为0,然后每隔1秒执行一次任务
        scheduledFuture = executorService.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
    }

    // 优雅关闭的方法
    public void shutdown() {
        // 取消任务
        scheduledFuture.cancel(true);

        // 关闭线程池
        executorService.shutdown();
        try {
            // 等待线程池中的所有任务都执行完毕或超时
            if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                // 强制关闭线程池,可能会导致正在执行的任务被中断
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            // 如果在等待过程中被中断,则也强制关闭线程池
            executorService.shutdownNow();
            Thread.currentThread().interrupt(); // 保留中断状态
        }
    }

    public static void main(String[] args) throws InterruptedException {
        PerpetualAsyncTask task = new PerpetualAsyncTask();

        // 模拟应用程序运行一段时间
        Thread.sleep(10000); // 等待10秒

        // 关闭永动任务
        task.shutdown();
    }
}

在这个示例中,我们创建了一个PerpetualAsyncTask类,它使用ScheduledExecutorService来提交一个永动任务。我们还提供了一个shutdown方法,用于优雅地关闭线程池和取消任务。

main方法中,我们创建了一个PerpetualAsyncTask实例,并让它运行一段时间(这里模拟为10秒)。然后,我们调用shutdown方法来关闭永动任务。

注意以下几点:

  • ScheduledFuture.cancel(true)用于尝试取消任务。如果任务已经开始执行,则取消可能不会立即生效。
  • executorService.shutdown()开始关闭线程池,不再接受新任务,但会等待已提交的任务执行完毕。
  • executorService.awaitTermination用于等待线程池中的任务执行完毕或超时。
  • 如果在等待过程中线程被中断,或者超时后仍有任务未执行完毕,我们使用executorService.shutdownNow()来强制关闭线程池,这可能会导致正在执行的任务被中断。

ExecutorService 

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class PerpetualExecutorAsyncTask {

    private static final ExecutorService executorService = Executors.newSingleThreadExecutor();

    public static void main(String[] args) {
        // 提交一个永动任务
        executorService.submit(() -> {
            while (true) {
                // 执行你的任务逻辑  
                System.out.println("永动任务正在运行...");

                // 可以根据需要添加休眠来减少CPU占用
                try {
                    Thread.sleep(1000); // 每秒执行一次
                } catch (InterruptedException e) {
                    // 如果线程被中断,可以选择退出循环或重新设置中断状态
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });

        // 主线程可以继续执行其他任务,或者可以选择等待所有任务完成
        // 例如,通过调用 executorService.shutdown() 和 executorService.awaitTermination()

        // 注意:不要在这里关闭executorService,否则永动任务会被中断
    }

    // 当程序结束时,确保优雅地关闭ExecutorService
    public static void shutdown() {
        executorService.shutdown(); // 不接受新任务
        try {
            // 等待所有任务完成,或者超时后退出
            if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                executorService.shutdownNow(); // 取消所有正在执行的任务并停止处理正在等待的任务
            }
        } catch (InterruptedException ie) {
            // 如果在等待过程中被中断,则重新设置中断状态并停止ExecutorService
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}

在这个例子中,我们创建了一个单线程的ExecutorService,并提交了一个永动任务。任务是一个无限循环,每次循环执行一些逻辑(在这个例子中只是打印一条消息),然后休眠一秒。

请注意,长时间运行的永动任务可能会消耗大量的系统资源,因此通常会在任务中添加一些休眠逻辑,以减少CPU的占用。此外,为了优雅地关闭ExecutorService,我们提供了一个shutdown方法,它首先尝试正常关闭(不再接受新任务,并等待现有任务完成),如果超时则尝试强制关闭(取消所有任务)。

在真实场景中,你可能还需要考虑如何优雅地处理任务的中断,例如在任务中捕获InterruptedException,并决定是重新设定中断状态并退出循环,还是只是重置中断状态并继续执行。

最后,确保在应用程序结束前调用shutdown方法来清理资源,避免资源泄露。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值