【设计模式系列】策略模式(二十四)

一、什么是策略模式

策略模式(Strategy Pattern)是软件设计模式中的一种行为型模式。++它定义了一系列算法,并将每一个算法封装起来,使它们可以互换使用++,算法的变化不会影响使用算法的用户。策略模式让算法的变化独立于使用算法的客户。

二、策略模式的角色

  1. 策略(Strategy)接口:定义所有支持的算法的公共接口。这个接口通常由一个或多个方法组成,这些方法将算法或行为的定义抽象化,使得它们可以互换使用。

  2. 具体策略(Concrete Strategy)类:实现策略接口的具体算法或行为。每个具体策略类都实现了策略接口,并提供了算法的具体实现。

  3. 上下文(Context)类:使用策略接口来引用具体的策略对象,维护一个对策略对象的引用,并可以设置和更换策略对象。

三、策略模式的典型应用

  1. 缓存机制:在需要缓存数据以提高性能的应用中,策略模式可以用来定义不同的缓存策略,如最近最少使用(LRU)、最不常用(LFU)等。

  2. 数据库访问:对于需要与多种数据库交互的应用程序,策略模式可以用来定义不同的数据库访问策略,以统一数据库操作接口。

  3. 数据序列化:在需要将数据序列化为不同格式(如JSON、XML、YAML等)的应用中,策略模式可以用来定义不同的序列化策略。

  4. 文件处理:在需要处理不同文件格式(如PDF、Word、Excel等)的应用中,策略模式可以用来定义不同的文件处理策略。

四、策略模式在ThreadPoolExecutor中的应用

ThreadPoolExecutor中,策略模式的应用体现在其拒绝策略(RejectedExecutionHandler)的设计上。当线程池中的任务队列满了,且线程数量达到最大值时,新加入的任务将被拒绝处理,这时会使用拒绝策略来处理这些任务。下面是策略模式在ThreadPoolExecutor中的具体应用,以及策略模式中每个角色的应用描述:

  1. 策略接口(Strategy) :在ThreadPoolExecutor中,RejectedExecutionHandler接口扮演了策略接口的角色,定义了rejectedExecution方法,用于处理任务拒绝的情况。

  2. 具体策略(Concrete Strategy)ThreadPoolExecutor提供了四种内置的拒绝策略实现,分别是AbortPolicyCallerRunsPolicyDiscardPolicyDiscardOldestPolicy

  3. 上下文(Context)ThreadPoolExecutor本身扮演了上下文角色,持有RejectedExecutionHandler的引用,并在需要时调用其rejectedExecution方法。

java 复制代码
import java.util.concurrent.*;

// 策略接口(Strategy)
interface MyRejectedExecutionHandler {
    void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}

// 具体策略A:直接抛出异常
class AbortPolicy implements MyRejectedExecutionHandler {
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        throw new RejectedExecutionException("Task " + r.toString() + " rejected from " +
                                              executor.toString());
    }
}

// 具体策略B:调用者运行任务
class CallerRunsPolicy implements MyRejectedExecutionHandler {
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        r.run();
    }
}

// 上下文(Context)
class MyThreadPoolExecutor extends ThreadPoolExecutor {
    private MyRejectedExecutionHandler handler;

    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, MyRejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
        this.handler = handler;
    }

    @Override
    public void reject(Runnable r) {
        handler.rejectedExecution(r, this);
    }
}

public class ThreadPoolExecutorStrategyPattern {
    public static void main(String[] args) {
        MyThreadPoolExecutor executor = new MyThreadPoolExecutor(
            2, // corePoolSize
            4, // maximumPoolSize
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(),
            Executors.defaultThreadFactory(),
            new AbortPolicy() // 使用具体策略A
        );

        // 提交任务
        for (int i = 0; i < 10; i++) {
            executor.execute(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " is running");
                }
            });
        }

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

在这个例子中,我们创建了一个MyThreadPoolExecutor实例,并传入了一个AbortPolicy拒绝策略。当提交的任务数超过线程池的容量时,就会触发拒绝策略。通过更换拒绝策略,我们可以灵活地改变线程池在任务拒绝时的行为,这就是策略模式在ThreadPoolExecutor中的应用。

相关推荐
API快乐传递者3 分钟前
淘宝京东数据分析实战指南:从指标体系到决策落地的全链路方法论
java·大数据·数据分析
vancece5 分钟前
JS实现堆 & 215.数组中的第K个最大元素
java·前端·javascript
就叫_这个吧5 分钟前
java springcloud熔断降级组件sentinel基础应用及nacos持久化处理
java·spring cloud·nacos·sentinel
SimonKing15 分钟前
Apache Fory JSON或许可以替代FastJson
java·后端·程序员
二炮手亮子22 分钟前
从 BIO、NIO、AIO 到多路复用与 Netty
策略模式·nio
程序员良辰24 分钟前
【TongWeb7的M11】 首次登录密码修改 & 开启控制台远程访问
java·中间件·tomcat
吴声子夜歌25 分钟前
Java面试——设计模式(四)
java·设计模式·面试
paopaokaka_luck26 分钟前
基于springboot3+vue3+uniapp的剧本杀预约小程序(AI角色对话、协同过滤算法、地图Api、Echarts图形化分析)
java·前端·spring boot·学习·echarts
一嘴一个橘子27 分钟前
idea 的 双击Shift 全局搜索
java·ide·intellij-idea
nvvas28 分钟前
最新版 IntelliJ IDEA 全面介绍:面向现代 Java 开发者的智能 IDE
java·ide·intellij-idea