IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【博学谷学习记录】超强总结,用心分享|狂野架构师之springBoot整合redisson、TaskExecutor -> 正文阅读

[Java知识库]【博学谷学习记录】超强总结,用心分享|狂野架构师之springBoot整合redisson、TaskExecutor

springBoot整合redisson、TaskExecutor

文章目录


前言

?Redisson - 是一个高级的分布式协调Redis客服端,能帮助用户在分布式环境中轻松实现一些Java的对象,本文使用的是哨兵模式;TaskExecutor线程池想必不用多说了。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Redisson

  1. 添加依赖
    <dependency>
        <groupId>org.redisson</groupId>
        <artifactId>redisson-spring-boot-starter</artifactId>
        <version>3.17.3</version>
    </dependency>
  2. 添加配置类
    
    import org.redisson.Redisson;
    import org.redisson.api.RedissonClient;
    import org.redisson.config.Config;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
    
    @Configuration
    public class RedissonConfig {
        @Value("${spring.redis.password}")
        private String password;
        @Value("${spring.redis.sentinel.master}")
        private String masterName;
        @Value("${spring.redis.sentinel.nodes}")
        private String sentinelNodes;
    
        @Bean
        public RedissonClient redissonClient() {
            Config config = new Config();
            String[] nodesArr = sentinelNodes.split(",");
            config.useSentinelServers()
                    .setMasterName(masterName)
                    //可以用"rediss://"来启用SSL连接
                    .addSentinelAddress("redis://" + nodesArr[0], "redis://" + nodesArr[1], "redis://" + nodesArr[2])
                    .setPassword(password);
            return Redisson.create(config);
        }
    }

二、TaskExecutor

  1. 配置文件
    略过
  2. 配置类
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.task.TaskExecutor;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
    
    import java.util.concurrent.ThreadPoolExecutor;
    
    @Configuration
    @EnableAsync
    @Slf4j
    public class ThreadConfig {
        @Bean
        public TaskExecutor taskExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            // 设置核心线程数
            executor.setCorePoolSize(5);
            // 设置最大线程数
            executor.setMaxPoolSize(20);
            // 设置队列容量
            executor.setQueueCapacity(100);
            // 设置线程活跃时间(秒)
            executor.setKeepAliveSeconds(100);
            // 设置默认线程名称
            executor.setThreadNamePrefix("Executor-");
            // 设置拒绝策略
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            // 等待所有任务结束后再关闭线程池
            executor.setWaitForTasksToCompleteOnShutdown(true);
            log.info("创建一个线程池 corePoolSize is [" + 5 + "] maxPoolSize is [" + 20 + "] queueCapacity is [" + 100 +
                    "] keepAliveSeconds is [" + 100 + "] namePrefix is [" + "Executor-" + "].");
            return executor;
        }
    }

三、测试

测试类


import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.task.TaskExecutor;


@Slf4j
@SpringBootTest
public class RedissonThreadTest {
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private TaskExecutor executor;

    @Test
    public void readData() {
        String key = "00";
        String s = redissonClient.getBucket(key).get().toString();
        //        boolean delete = redissonClient.getBucket(key).delete();
        System.out.println(s);
    }

    @Test
    public void writeData() {
        String key = "maotaijiu";
        String value = "1";
        redissonClient.getBucket(key).set(value);
    }

    @Test
    public void forData() {
        String key = "maotaijiu1";
        String value = "100";
        redissonClient.getBucket(key).set(value);
        for (int i = 1; i <= 200; i++) {
            executor.execute(() -> {
                System.out.println("线程名称:" + Thread.currentThread().getName());
                seckillMaotai7(key);
            });
        }
    }

    @Test
    public void seckillMaotai7(String mtKey) {
        String lockKey = "lockKey";
        RLock lock = redissonClient.getLock(lockKey);
        System.out.println("线程名称:" + Thread.currentThread().getName()+"ok1");
        //加锁
        lock.lock();
        System.out.println("线程名称:" + Thread.currentThread().getName()+"ok2");
        try {
            Integer count = Integer.parseInt(redissonClient.getBucket(mtKey).get().toString());
            //如果还有库存
            if (count > 0) {
                //                Thread.sleep(5);
                //抢到了茅台,库存减一
                redissonClient.getBucket(mtKey).set(count - 1);
                //后续操作 do something
                System.out.println("线程名称:" + Thread.currentThread().getName()+"我抢到茅台" + count + "了!");
                return;
            } else {
                System.out.println("线程名称:" + Thread.currentThread().getName()+"卖完了,下次再来");
                return;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //释放锁
            lock.unlock();
            System.out.println("线程名称:" + Thread.currentThread().getName()+"线程名称:" + Thread.currentThread().getName()+"释放锁");
        }
        System.out.println("dont get lock");
        return;
    }
}

四、线程池要点

线程池处理任务流程:

当往线程池中提交新任务时,线程池主要流程如下:
核心线程数 -> 线程队列 -> 最大线程数 -> 拒绝策略

  1. 如果池中任务数 < corePoolSize (核心线程数),创建新线程立即执行任务
  2. 如果池中任务数 > corePoolSize,新任务放到缓存队列当中等待执行
  3. 队列满,线程数量<maxPoolSize,新建线程立即执行任务
  4. 队列满,线程数量>=maxPoolSize,使用拒绝策略拒绝

拒绝策略:

ThreadPoolExecutor.AbortPolicy

ThreadPoolExecutor 默认策略?

直接抛出java.util.concurrent.RejectedExecutionException异常

ThreadPoolExecutor.DiscardPolicy放弃当前任务,并且不会抛出任何异常
ThreadPoolExecutor.DiscardOldestPolicy会将队列中最早添加的元素移除,再尝试添加,如果失败则按该策略不断重试
ThreadPoolExecutor.CallerRunsPolicy

由调用线程(提交任务的线程)处理该任务,如果调用线程是主线程,那么主线程会调用执行器中的execute方法来执行改任务

总结


可不容易呢,搞了两天

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-09-30 00:38:26  更:2022-09-30 00:42:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/25 23:00:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码