文章三:深入了解Executor框架

目录

3.1 引言

Executor框架的重要性

本文的内容结构

3.2 Executor、ExecutorService和ThreadPoolExecutor

各类Executor的介绍和使用方法

创建和管理线程池的示例

使用FixedThreadPool

3.3 ScheduledExecutorService

定时任务的调度和管理

创建定时任务

创建周期性任务

示例代码和应用场景

示例代码

应用场景

结论


3.1 引言

Executor框架的重要性

在Java并发编程中,直接使用Thread类和Runnable接口来管理线程显得过于底层和繁琐。为了更好地管理线程池和任务,Java提供了Executor框架。该框架简化了并发编程,使得任务的提交和线程的管理更加灵活和高效。通过Executor框架,开发者可以专注于任务本身,而不需要处理复杂的线程生命周期管理。此外,Executor框架提供了线程池、定时任务调度等高级功能,大大提升了并发编程的便捷性和性能。

本文的内容结构

本文将详细介绍Java中Executor框架的使用,主要内容包括:

  1. ExecutorExecutorServiceThreadPoolExecutor
  2. 创建和管理线程池的示例
  3. ScheduledExecutorService的使用方法

3.2 Executor、ExecutorService和ThreadPoolExecutor

各类Executor的介绍和使用方法

Executor是一个顶级接口,定义了任务提交的基础方法:

public interface Executor {
    void execute(Runnable command);
}

ExecutorService扩展了Executor接口,提供了管理终止和生成Future以跟踪一个或多个异步任务执行的功能:

public interface ExecutorService extends Executor {
    void shutdown();
    List<Runnable> shutdownNow();
    boolean isShutdown();
    boolean isTerminated();
    boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;
    <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;
    <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException;
}

ThreadPoolExecutorExecutorService的实现类,提供了灵活的线程池功能:

public class ThreadPoolExecutor extends AbstractExecutorService {
    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue);
    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory);
    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler);
    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler);
}

创建和管理线程池的示例

使用FixedThreadPool
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedThreadPoolDemo {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(5); // 创建包含5个线程的固定线程池

        for (int i = 0; i < 10; i++) {
            Runnable task = new Task(i);
            executor.execute(task);
        }

        executor.shutdown(); // 关闭线程池
    }
}

class Task implements Runnable {
    private final int taskId;

    public Task(int taskId) {
        this.taskId = taskId;
    }

    @Override
    public void run() {
        System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());
    }
}

使用CachedThreadPool

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

public class CachedThreadPoolDemo {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool(); // 创建一个根据需要创建新线程的线程池

        for (int i = 0; i < 10; i++) {
            Runnable task = new Task(i);
            executor.execute(task);
        }

        executor.shutdown(); // 关闭线程池
    }
}

class Task implements Runnable {
    private final int taskId;

    public Task(int taskId) {
        this.taskId = taskId;
    }

    @Override
    public void run() {
        System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());
    }
}

使用ScheduledThreadPool

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

public class ScheduledThreadPoolDemo {
    public static void main(String[] args) {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(5); // 创建包含5个线程的调度线程池

        for (int i = 0; i < 5; i++) {
            Runnable task = new Task(i);
            executor.schedule(task, 2, TimeUnit.SECONDS); // 延迟2秒执行任务
        }

        executor.shutdown(); // 关闭线程池
    }
}

class Task implements Runnable {
    private final int taskId;

    public Task(int taskId) {
        this.taskId = taskId;
    }

    @Override
    public void run() {
        System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());
    }
}

3.3 ScheduledExecutorService

定时任务的调度和管理

ScheduledExecutorService接口扩展了ExecutorService,提供了定时任务的调度功能。可以使用它来调度一次性任务或周期性任务。

创建定时任务

可以使用schedule方法调度一次性任务:

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
Runnable task = () -> System.out.println("Scheduling: " + System.nanoTime());
executor.schedule(task, 3, TimeUnit.SECONDS);
executor.shutdown();

在这个示例中,任务将在3秒后执行。

创建周期性任务

可以使用scheduleAtFixedRate方法调度周期性任务:

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
Runnable task = () -> System.out.println("Scheduling: " + System.nanoTime());
executor.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS); // 每秒执行一次任务

可以使用scheduleWithFixedDelay方法调度具有固定延迟的周期性任务:

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
Runnable task = () -> System.out.println("Scheduling: " + System.nanoTime());
executor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS); // 每次任务执行完毕后等待1秒再执行

示例代码和应用场景

示例代码

以下是一个使用ScheduledExecutorService调度定时任务的完整示例:

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

public class ScheduledExecutorServiceDemo {
    public static void main(String[] args) {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
        
        Runnable task = () -> System.out.println("Scheduling: " + System.nanoTime());

        // 调度一次性任务,延迟3秒执行
        executor.schedule(task, 3, TimeUnit.SECONDS);

        // 调度周期性任务,每秒执行一次
        executor.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);

        // 调度具有固定延迟的周期性任务,每次任务执行完毕后等待1秒再执行
        executor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS);

        // 一段时间后关闭executor,避免程序无限运行
        executor.schedule(() -> {
            executor.shutdown();
            System.out.println("Executor shut down.");
        }, 10, TimeUnit.SECONDS);
    }
}
应用场景

ScheduledExecutorService常用于以下场景:

  • 定时任务:如定期备份数据、定期生成报表等。
  • 周期性任务:如心跳检测、定时清理缓存等。
  • 延迟任务:如延迟执行任务、任务重试等。

结论

本文深入介绍了Java中的Executor框架,重点介绍了ExecutorExecutorServiceThreadPoolExecutorScheduledExecutorService的使用方法。在实际开发中,根据具体需求选择合适的线程池和任务调度方式,可以大大提升应用程序的性能和可维护性。希望本文对你有所帮助,敬请期待专栏的下一篇文章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深度学习客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值