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

news2024/12/14 0:54:47

一、什么是策略模式

策略模式(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方法。

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中的应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2259031.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spark SQL 执行计划解析源码分析

本文用于记录Spark SQL执行计划解析的源码分析。文中仅对关键要点进行提及&#xff0c;无法面面具到&#xff0c;仅描述大体的框架。 Spark的Client有很多种&#xff0c;spark-sql&#xff0c;pyspark&#xff0c;spark- submit&#xff0c;R等各种提交方式&#xff0c;这里以…

(2)Spring Security - 了解UserDetailsService

目录 1.认识UserDetailsService1.1.认识UserDetails1.2.UserDetailsService的默认实现 -- InMemoryUserDetailsManager 2.用户信息存储在MySQL数据库中2.1.添加依赖2.2.配置MySQL和Mybatis2.3.在数据库中添加用户信息2.4.添加数据库实体类2.5.编写Mybatis代码2.6.实现UserDetai…

智能设备安全-固件逆向分析

固件逆向分析实验报告-20241022 使用固件常用逆向分析工具&#xff0c;对提供的固件进行文件系统提取&#xff0c;并记录逆向分析实验过程&#xff0c;提交实验报告&#xff08;报告要求图文并茂&#xff0c;对涉及到的关键步骤附截图说明&#xff09;。具体任务如下&#xff1…

图形编辑器基于Paper.js教程17:图像转gcode前的处理,灰度,黑白,抖动

好久没有正经写博客了&#xff0c;前一段时间一直在备考中级项目管理&#xff0c;再加上项目开发只有自己一个人&#xff0c;每天忙的飞起。有闲暇时间也不想写&#xff0c;其中一部分原因也是因为很多简单问题&#xff0c;AI就能回答的很好。而对复杂的问题&#xff0c;也不是…

AI大模型学习笔记|人工智能的发展历程、智能体的发展、机器学习与深度学习的基本理论

学习链接&#xff1a;冒死上传&#xff01;价值2W的大模型入门到就业教程分享给大家&#xff01;轻松打造专属大模型助手&#xff0c;—多模态、Agent、LangChain、ViT、NLP_哔哩哔哩_bilibili 百度网盘自己整理的笔记&#xff1a; 通过网盘分享的文件&#xff1a;1-人工智能的…

qt 设置系统缩放为150%,导致的文字和界面的问题

1 当我们设置好布局后&#xff0c;在100%的设置里面都是正常的&#xff0c;但是当我们修改缩放为150%后&#xff0c;字体图标&#xff0c;界面大小就出现问题了&#xff0c;这就需要我们设置一些参数。 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QCoreAppl…

linux-15 关于shell(十四)printenv,hash,环境变量

此前没有用过linux&#xff0c;可能有些觉得很奇怪&#xff0c;就觉得我们在这敲来敲去命令干什么&#xff1f;为什么不使用双击这种方式来操作&#xff1f;大家知道&#xff0c;在Windows里面&#xff0c;其实我们双击也无非就是告诉我们shell需要将这个命令发送在内核上启动的…

虚拟机如何使用物理机的公私钥

一、生成公私钥&#xff08;如果没有的话&#xff09; 使用如下指令生成 生成RSA公私钥 ssh-keygen 生成EdDSA公私钥 ssh-keygen -t ed25519 Windows目录 linux会直接生成在当前目录下。 二、导出 一般都是从windows系统导入到linux系统。 可以直接将公私钥文件复制到虚拟机…

SpringBoot【十一】mybatis-plus实现多数据源配置,开箱即用!

一、前言&#x1f525; 环境说明&#xff1a;Windows10 Idea2021.3.2 Jdk1.8 SpringBoot 2.3.1.RELEASE 正常情况下我们在开发系统的时候都是使用一个数据源&#xff0c;但是由于有些项目同步数据的时候不想造成数据库io消耗压力过大&#xff0c;便会一个项目对应多个数据源…

前端报错npm ERR cb() never called问题

环境使用node版本v14.21.3&#xff0c;npm版本6.14.18 1.问题描述 1.1使用npm install后报错 npm ERR! cb() never called!npm ERR! This is an error with npm itself. Please report this error at: npm ERR! ? ? <https://npm.community>npm ERR! A complete log…

C++ STL Cookbook STL算法

目录 std::copy 将容器元素合并为一个字符串 使用 std::sort 对容器进行排序 使用 std::transform 修改容器 在容器中查找项目 使用 std::sample 采样数据集 (写在前面&#xff1a;笔者前段时间备战考试和比赛了&#xff0c;现在回来继续更新) STL实际上提供了非常非常丰…

SpringBoot【十】mybatis之xml映射文件>、<=等特殊符号写法!

一、前言&#x1f525; 环境说明&#xff1a;Windows10 Idea2021.3.2 Jdk1.8 SpringBoot 2.3.1.RELEASE 在利用mybatis进行开发的时候&#xff0c;编写sql时可能少不了>、<等比较符号&#xff0c;但是在mapper映射文件中直接使用是不行的&#xff0c;会报错&#xff0…

单元测试SpringBoot

添加测试专用属性 加载测试专用bean Web环境模拟测试 数据层测试回滚 测试用例数据设定

每天40分玩转Django:简介和环境搭建

Django简介和环境搭建 一、课程概述 学习项目具体内容预计用时Django概念Django框架介绍、MVC/MTV模式、Django特点60分钟环境搭建Python安装、pip配置、Django安装、IDE选择45分钟创建项目项目结构、基本配置、运行测试75分钟实战练习创建个人博客项目框架60分钟 二、Djang…

Jenkins参数化构建详解(This project is parameterized)

本文详细介绍了Jenkins中不同类型的参数化构建方法&#xff0c;包括字符串、选项、多行文本、布尔值和git分支参数的配置&#xff0c;以及如何使用ActiveChoiceParameter实现动态获取参数选项。通过示例展示了传统方法和声明式pipeline的语法 文章目录 1. Jenkins的参数化构建1…

Windows安装WSL子系统及docker,以及WSL和docker配置、使用及问题解决

在Windows操作系统中,Ubuntu子系统(也称为Windows Subsystem for Linux, WSL)为开发者提供了一个在Windows环境下运行Linux环境的平台。然而,有时用户在按照Ubuntu子系统或者使用WSL时,可能会遇到各种问题,下面总结一下解决方式。 想要在Windows上安装Docker(实际上是基…

Linux中的线程

目录 线程的概念 进程与线程的关系 线程创建 线程终止 线程等待 线程分离 原生线程库 线程局部存储 自己实现线程封装 线程的优缺点 多线程共享与独占资源 线程互斥 互斥锁 自己实现锁的封装 加锁实现互斥的原理 死锁 线程同步 线程的概念 回顾进程相关概念 …

shell编程(完结)

shell编程&#xff08;完结&#xff09; 声明&#xff01; 学习视频来自B站up主 ​泷羽sec​​ 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章 笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其…

ctfshow-web 151-170-文件上传

151. 我们首先想到就是上传一句话木马。但是看源代码限制了png。 &#xff08;1&#xff09;改前端代码。 这里是前端限制了上传文件类型&#xff0c;那我们就改一下就好了嘛,改成php。 这里直接修改不行&#xff0c;给大家推荐一篇简短文章&#xff0c;大家就会了&#xff08…

Docker的初识

目录 1. 容器技术发展史1.1 Jail 时代1.2 云时代1.3 云原生时代1.3.1 Google & Docker 竞争1.3.2 k8s 成为云原生事实标准 2. 虚拟化和容器化的概念2.1 什么是虚拟化、容器化2.2 为什么要虚拟化、容器化&#xff1f;2.3 虚拟化实现方式2.3.1 应用程序执行环境分层2.3.2 虚拟…