重封装Ehcache与Redis模板以便于一二级缓存同步数据(二)

news2025/1/19 2:55:59

参考: 一级缓存二级缓存的获取与更新顺序(一) 

                                   简单封装Ehcache与RedisTemplate模版                                       



                 



                   通常使用一二级缓存时,必须保持一二级缓存数据数据与数据库中数据保持一致 ;此时可以简单封装下,一二级缓存的相关接口,便于我们同步数据操作;



                                                           Ehcache封装


package org.jd.auth.data.security.server.base;

import lombok.extern.slf4j.Slf4j;
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.Map;


/**
 * ehcache缓存服务组件:
 * 这样重写Ehcache缓存组件的目的在于使用一级缓存和二级缓存时,便于及时同步一二级缓存的数据
 * @Author: yh19166
 */
@Slf4j
@Component
public class SSOEhcacheService {

    @Resource
    @Qualifier("ehCacheManager")
    private CacheManager cacheManager;

    /**
     * @param cacheName 为ehcache.xml文件中配置缓存的名称
     * @return
     */
    public Cache<String, Object> getCache(String cacheName) {
        Cache cache = this.cacheManager.getCache(cacheName, String.class, Object.class);
        if (ObjectUtils.isEmpty(cache)) { // 避免了Optional对象为Optional.empty()空对象;ObjectUtils.isEmpty(方法源代码已经作了判断)
            log.error("SSOEhcacheService.getCache.cacheName[{}] is not exit", cacheName);
        }
        return cache;
    }

    /**
     * 根据cacheKey获取对应的值
     *
     * @param cacheName 配置文件中配置缓存的名称
     * @param cacheKey  缓存Key
     * @return {@link Object}
     */
    public Object get(String cacheName, String cacheKey) {
        Cache<String, Object> cache = getCache(cacheName);
        if (ObjectUtils.isEmpty(cache)) {
            log.error("SSOEhcacheService.do.get method,[{}] is not exit", cacheName);
            return null;
        }
        return cache.get(cacheKey);
    }

    /**
     * @param cacheName 配置文件中配置缓存的名称
     * @param cacheKey  缓存key
     * @param value     缓存值
     */
    public void put(String cacheName, String cacheKey, Object value) {
        Cache<String, Object> cache = getCache(cacheName);
        if (ObjectUtils.isEmpty(cache)) {
            log.error("SSOEhcacheService.do.put method,[{}] is not exit", cacheName);
            return;
        }
        cache.put(cacheKey, value);
    }

    /**
     * @param cacheName 配置文件中配置缓存的名称
     * @param value     缓存值
     */
    public void putAll(String cacheName, Map<String, Object> value) {
        Cache<String, Object> cache = getCache(cacheName);
        if (ObjectUtils.isEmpty(cache)) {
            log.error("SSOEhcacheService.do.putAll method,[{}] is not exit", cacheName);
            return;
        }
        cache.putAll(value);
    }

    /**
     * 判断缓存key是否存在
     *
     * @param cacheName 配置文件中配置缓存的名称
     * @param key       缓存key
     * @return {@link Boolean}
     */
    public boolean exist(String cacheName, String key) {
        Cache<String, Object> cache = getCache(cacheName);
        if (ObjectUtils.isEmpty(cache)) {
            log.error("SSOEhcacheService.do.exist method,[{}] is not exit", cacheName);
            return false;
        }
        return cache.containsKey(key);

    }

    /**
     * 删除指定key的缓存
     *
     * @param cacheName 配置文件中配置缓存的名称
     * @param key       缓存key
     */
    public void evict(String cacheName, String key) {
        Cache<String, Object> cache = getCache(cacheName);
        if (ObjectUtils.isEmpty(cache)) {
            log.error("SSOEhcacheService.do.evict method,[{}] is not exit", cacheName);
            return;
        }
        cache.remove(key);
    }
}


                                               RedisTemplate模版简单封装



package org.jd.auth.data.security.server.base;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Redis通常作为二级缓存
 * Redis缓存对: spring-boot-starter-data-redis的模版(RedisTemplate)的进一步封装:
 * @Author: yh19166
 */
@Slf4j
@Component
public class SSORedisService {
    @Resource
    private RedisTemplate<Serializable, Object> redisTemplate;

    /**
     * 批量删除对应的value
     *
     * @param keys
     */
    public void remove(String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }

    /**
     * 正则批量删除key 例:h?llo matches hello, hallo
     *
     * @param pattern
     */
    public void removePattern(String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (!keys.isEmpty()) {
            redisTemplate.delete(keys);
        }
    }

    /**
     * 正则获取多个缓存key 例:h?llo matches hello, hallo
     *
     * @param pattern
     */
    public Set<Serializable> patternKeys(String pattern) {
        return redisTemplate.keys(pattern);
    }

    /**
     * 正则key获取多个缓存
     *
     * @param pattern
     * @return 返回Set >-String 集合
     */
    public Set<String> patternKeysIsStr(String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        Set<String> dataSet = new HashSet<>();
        for (Serializable obj : keys) {
            dataSet.add(obj.toString());
        }
        return dataSet;
    }

    /**
     * 删除对应的value
     *
     * @param key
     */
    public void remove(String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }

    /**
     * 判断缓存中是否有对应的value
     *
     * @param key
     * @return
     */
    public boolean exists(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 设置key的过期时间 单位(秒)
     *
     * @param key
     * @param expireTime
     * @return boolean
     */
    public boolean setKeyExpire(String key, Long expireTime) {
        return redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
    }

    /**
     * 读取缓存
     *
     * @param key
     * @return
     */
    public Object getObject(String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }

    /**
     * 写入缓存
     *
     * @param key
     * @param value
     * @return
     */
    public boolean setObject(String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            log.warn("setObject 返回异常 " + e.getMessage());
        }
        return result;
    }

    /**
     * 写入缓存设置并设置时间 时间单位(秒)
     *
     * @param key
     * @param value
     * @return
     */
    public boolean setObjectAndExpire(String key, Object value, Long expireTime) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            log.warn("setObjectAndExpire 返回异常 " + e.getMessage());
        }
        return result;
    }

    /**
     * 缓存List数据 右侧入栈
     *
     * @param key      缓存的键值
     * @param dataList 待缓存的List数据
     * @return 缓存的对象
     */
    public boolean setList(String key, List<Object> dataList) {
        boolean result = false;
        try {
            ListOperations<Serializable, Object> listOperation = redisTemplate.opsForList();
            if (null != dataList) {
                int size = dataList.size();
                for (int i = 0; i < size; i++) {
                    listOperation.rightPush(key, dataList.get(i));
                }
            }
            result = true;
        } catch (Exception e) {
            log.warn("setList 返回异常 " + e.getMessage());
        }
        return result;
    }

    /**
     * 缓存List数据 右侧入栈 并设置过期时间 单位(秒)
     *
     * @param key      缓存的键值
     * @param dataList 待缓存的List数据
     * @return 缓存的对象
     */
    public boolean setListAndExpire(String key, List<Object> dataList, Long expireTime) {
        boolean result = false;
        try {
            ListOperations<Serializable, Object> listOperation = redisTemplate.opsForList();
            if (null != dataList) {
                int size = dataList.size();
                for (int i = 0; i < size; i++) {
                    listOperation.rightPush(key, dataList.get(i));
                }
            }
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);

            result = true;
        } catch (Exception e) {
            log.warn("setListAndExpire 返回异常 " + e.getMessage());
        }
        return result;
    }

    /**
     * 获得缓存的list对象
     *
     * @param key 缓存的键值
     * @return 缓存键值对应的数据
     */
    public List<Object> getList(String key) {
        ListOperations<Serializable, Object> listOperation = redisTemplate.opsForList();
        return listOperation.range(key, 0, -1);
    }

    /**
     * 获得缓存的list对象 出栈的方式获取数据 左侧出栈
     *
     * @param key 缓存的键值
     * @return 缓存键值对应的数据
     */
    public List<Object> getListPop(String key) {
        List<Object> dataList = new ArrayList<>();
        ListOperations<Serializable, Object> listOperation = redisTemplate.opsForList();
        Long size = listOperation.size(key);
        for (int i = 0; i < size; i++) {
            dataList.add(listOperation.leftPop(key));
        }
        return dataList;
    }

    /**
     * 缓存Set
     *
     * @param key     缓存键值
     * @param dataSet 缓存的数据
     * @return 缓存数据的对象
     */
    public boolean setSet(String key, Set<Object> dataSet) {
        boolean result = false;
        try {
            BoundSetOperations<Serializable, Object> setOperation = redisTemplate.boundSetOps(key);
            Iterator<Object> it = dataSet.iterator();
            while (it.hasNext()) {
                setOperation.add(it.next());
            }
            result = true;
        } catch (Exception e) {
            log.warn("setSet 返回异常 " + e.getMessage());
        }
        return result;
    }

    /**
     * 缓存Set并设置失效时间 单位(秒)
     *
     * @param key     缓存键值
     * @param dataSet 缓存的数据
     * @return 缓存数据的对象
     */
    public boolean setSetAndExpire(String key, Set<Object> dataSet, Long expireTime) {
        boolean result = false;
        try {
            BoundSetOperations<Serializable, Object> setOperation = redisTemplate.boundSetOps(key);
            Iterator<Object> it = dataSet.iterator();
            while (it.hasNext()) {
                setOperation.add(it.next());
            }
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            log.warn("setSetAndExpire 返回异常 " + e.getMessage());
        }
        return result;
    }

    /**
     * 获得缓存的set
     *
     * @param key
     * @param
     * @return
     */
    public Set<Object> getSet(String key) {
        BoundSetOperations<Serializable, Object> operation = redisTemplate.boundSetOps(key);
        return operation.members();
    }

    /**
     * 获得缓存的set 已出栈方式获取
     *
     * @param key
     * @param
     * @return
     */
    public Set<Object> getSetPop(String key) {
        Set<Object> dataSet = new HashSet<>();
        BoundSetOperations<Serializable, Object> operation = redisTemplate.boundSetOps(key);
        Long size = operation.size();
        for (int i = 0; i < size; i++) {
            dataSet.add(operation.pop());
        }
        return dataSet;
    }

    /**
     * 缓存Hash(字典,哈希表)
     *
     * @param key
     * @param dataMap
     * @return
     */
    public boolean setMap(String key, Map<String, Object> dataMap) {
        boolean result = false;
        try {
            HashOperations<Serializable, Object, Object> hashOperations = redisTemplate.opsForHash();
            if (null != dataMap) {

                for (Map.Entry<String, Object> entry : dataMap.entrySet()) {

                    hashOperations.put(key, entry.getKey(), entry.getValue());
                }

            }
            result = true;
        } catch (Exception e) {
            log.warn("setMap 返回异常 " + e.getMessage());
        }
        return result;
    }

    /**
     * 缓存Hash(字典,哈希表)并设置过期时间 单位(秒)
     *
     * @param key
     * @param dataMap
     * @return
     */
    public boolean setMapAndExpire(String key, Map<String, Object> dataMap, Long expireTime) {
        boolean result = false;
        try {
            HashOperations<Serializable, Object, Object> hashOperations = redisTemplate.opsForHash();
            if (null != dataMap) {

                for (Map.Entry<String, Object> entry : dataMap.entrySet()) {

                    hashOperations.put(key, entry.getKey(), entry.getValue());
                }

            }
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            log.warn("setMapAndExpire 返回异常 " + e.getMessage());
        }
        return result;
    }

    /**
     * 缓存Hash(字典,哈希表)并设置过期时间 单位(秒) 值类型为 Map<String, String>
     *
     * @param key
     * @param dataMap
     * @return
     */
    public boolean setStrMapAndExpire(String key, Map<String, String> dataMap, Long expireTime) {
        boolean result = false;
        try {
            HashOperations<Serializable, Object, Object> hashOperations = redisTemplate.opsForHash();
            if (null != dataMap) {

                for (Map.Entry<String, String> entry : dataMap.entrySet()) {

                    hashOperations.put(key, entry.getKey(), entry.getValue());
                }

            }
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            log.warn("setMapAndExpire 返回异常 " + e.getMessage());
        }
        return result;
    }

    /**
     * 获得缓存的Hash(字典,哈希表)
     *
     * @param key
     * @param
     * @return
     */
    public Map<String, Object> getMap(String key) {
        HashOperations<Serializable, String, Object> hashOperations = redisTemplate.opsForHash();

        return hashOperations.entries(key);
    }

    /**
     * 根据key和hashKey获得缓存Hash中的值
     *
     * @param key
     * @param
     * @return String
     */
    public String getMapByHashKey(String key, String hashKey) {
        HashOperations<Serializable, String, Object> hashOperations = redisTemplate.opsForHash();
        return (String) hashOperations.get(key, hashKey);
    }

    /**
     * 缓存有序Set 默认score为添加的顺序
     *
     * @param key     缓存键值
     * @param dataSet 缓存的数据
     * @return 缓存数据的对象
     */
    public boolean setZSet(String key, Set<Object> dataSet) {
        boolean result = false;
        try {
            BoundZSetOperations<Serializable, Object> setOperation = redisTemplate.boundZSetOps(key);
            int size = dataSet.size();
            Iterator<Object> it = dataSet.iterator();
            while (it.hasNext()) {
                setOperation.add(it.next(), --size);
            }
            result = true;
        } catch (Exception e) {
            log.warn("setZSet 返回异常 " + e.getMessage());
        }
        return result;
    }

    /**
     * 缓存有序Set 并添加失效时间单位(秒) 默认score为添加的顺序
     *
     * @param key     缓存键值
     * @param dataSet 缓存的数据
     * @return 缓存数据的对象
     */
    public boolean setZSetAndExpire(String key, Set<Object> dataSet, Long expireTime) {
        boolean result = false;
        try {
            BoundZSetOperations<Serializable, Object> setOperation = redisTemplate.boundZSetOps(key);
            int size = dataSet.size();
            Iterator<Object> it = dataSet.iterator();
            while (it.hasNext()) {
                if (size > 0) {
                    setOperation.add(it.next(), size--);
                }
            }
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            log.warn("setZSetAndExpire 返回异常 " + e.getMessage());
        }
        return result;
    }

    /**
     * 缓存有序Set
     *
     * @param key
     * @return 缓存数据的对象
     */
    public Set<Object> getZSetRange(String key) {
        BoundZSetOperations<Serializable, Object> operation = redisTemplate.boundZSetOps(key);
        return operation.range(0, -1);

    }

    /**
     * 根据key 返回该key的存活时间 单位(秒)
     *
     * @param key 缓存键值
     * @return key 的存活时间 单位(秒)
     */
    public Long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 根据key 设置时间 单位(秒)
     *
     * @param key 缓存键值
     * @return boolean
     */
    public Boolean setUpExpire(String key, Long expireTime) {
        return redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
    }

    /**
     * 清空redis 所有数据
     *
     * @return 成功返回 ok
     */
    public String flushDb() {
        return (String) redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public String doInRedis(RedisConnection connection) {
                connection.flushDb();
                return "ok";
            }
        });
    }

    /**
     * @return 查看redis里有多少数据
     */
    public long dbSize() {
        return (long) redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Long doInRedis(RedisConnection connection) {
                return connection.dbSize();
            }
        });
    }

    /**
     * 检查是否连接成功
     *
     * @return 成功则返回 PONG 失败什么都不会留下
     */
    public String ping() {
        return (String) redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public String doInRedis(RedisConnection connection) {
                return connection.ping();
            }
        });
    }

    /**
     * 生成自增长
     * @param key
     * @return {@link Long}
     */
    public Long createAutoNo(String key) {
        return redisTemplate.opsForValue().increment(key, 1);
    }
}

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

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

相关文章

数据结构(王道)——线性表的存储结构之链表存储

线性表的链表存储&#xff1a; 一、单链表定义&#xff1a; 用代码定义一个单链表&#xff1a; 不带头结点的单链表定义&#xff1a; 带头结点的单链表定义&#xff1a; 单链表定义总结&#xff1a; 二、单链表的基本操作&#xff08;插入删除查找&#xff09; 1、插入 如何在…

手机图片怎么转pdf格式?这几个图片转换方式了解一下

手机图片怎么转pdf格式&#xff1f;将图片转换为PDF的应用场景非常广泛。例如&#xff0c;你可以将多张照片转换为PDF&#xff0c;然后将其作为一本电子相册保存。你也可以将多张图片转换为PDF&#xff0c;然后将其作为一份报告或文档的附件发送给他人。此外&#xff0c;许多人…

⌈C++⌋深度剖析构造、拷贝构造与赋值运算符重载——深浅拷贝、explicit、类型转换等

目录 一、认识拷贝构造函数 1、什么是拷贝构造 2、深拷贝与浅拷贝 3、编译器可以绕过拷贝构造函数&#xff08;C Primer P442&#xff09; 4、explicit修饰 二、认识赋值运算符重载 1、赋值运算符重载格式 2、默认赋值运算符重载 3、赋值运算符都必须定义为成员函数 …

内网使用JRebel及踩坑点

目录 前言外网正常使用JRebel下载安装插件授权 内网授权方式搭建本地授权服务器安装JRebel的电脑网络切换为手机热点 设置脱机离线模式设置自动重新部署时间间隔使用JRebel之前需要的配置项勾选compiler -> build project automatically设置代码热部署配置JRebel热部署的项目…

979.在二叉树中分配硬币

979.在二叉树中分配硬币 给定一个有 N 个结点的二叉树的根结点 root&#xff0c;树中的每个结点上都对应有 node.val 枚硬币&#xff0c;并且总共有 N 枚硬币。 在一次移动中&#xff0c;我们可以选择两个相邻的结点&#xff0c;然后将一枚硬币从其中一个结点移动到另一个结点…

Ubuntu新版静态IP设置

cd /etc/netplan直接编辑 sudo vi /etc/netplan/00-installer-config.yaml#network: # ethernets: # ens160: # dhcp4: true # version: 2network:version: 2ethernets:ens160:dhcp4: noaddresses: [172.17.10.23/24]optional: truegateway4: 172.17.10.1nameservers…

【Linux】无法连外网,只能用压缩包,环境搭建流程

【Linux】无法连外网&#xff0c;只能用压缩包&#xff0c;环境搭建流程 【一】JDK&#xff08;1&#xff09;下载jdk安装包&#xff08;2&#xff09;解压安装包&#xff08;3&#xff09;修改环境变量&#xff08;4&#xff09;测试是否安装成功 【二】安装mysql【1】5.7版本…

Prometheus、Grafana使用

文章目录 系统性能监控相关命令lscputopfreehtopdstatglancesiftopiptrafnethogs 监控软件Prometheus安装、使用将promethues做成服务监控其他机器 exportergrafana配置、使用 系统性能监控 相关命令 lscpu lscpu 是一个 Linux 命令&#xff0c;用于显示关于 CPU&#xff08…

使用git克隆非自己账号的项目

在地址的中https://或者http://后添加要使用的 账号名项目地址&#xff0c;就会提示输入对应账号的密码&#xff0c;进行克隆。 如果克隆别人的项目&#xff0c;你将别人给你的项目地址克隆&#xff0c;此时身份验证是别人的用户名&#xff0c;这时你输入自己的密码就会验证失败…

Centos 8 / TencentOS Server 3.1 安装 docker-ce

目录 前言安装 docker-ce设置Docker Hub 镜像缓存参考 前言 TencentOS Server 3.1(与 CentOS 8用户态完全兼容&#xff0c;配套基于社区5.4 LTS 内核深度优化的 tkernel4版本) 安装 docker-ce 先卸载老版本&#xff0c;没有老版本的跳过 yum remove docker \docker-client \d…

DBeaver连接华为高斯数据库 DBeaver连接Gaussdb数据库 DBeaver connect Gaussdb

DBeaver连接华为高斯数据库 DBeaver连接Gaussdb数据库 DBeaver connect Gaussdb 一、概述 华为GaussDB出来已经有一段时间&#xff0c;最近工作中刚到Gauss数据库。作为coder&#xff0c;那么如何通过可视化工具来操作Gauss呢&#xff1f; 本文将记录使用免费、开源的DBeaver来…

遥感目标检测(1)--R3Det

目录 一、概述 二、三个挑战 三、网络架构​编辑 1、旋转RetinaNet 2、精细化旋转RetinaNet 3、与RoIAlign&#xff08;感兴趣区域插值&#xff09;进行比较 4、消融实验与对比实验 一、概述 R3Det论文中提到一个端到端的精细化的单级旋转检测器&#xff0c;通过从粗到细…

JMeter自定义日志与日志分析

1 JMeter日志概览 JMeter与Java程序一样&#xff0c;会记录事件日志&#xff0c;日志文件保存在bin目录中&#xff0c;名称为jmeter.log。当然&#xff0c;我们也可以在面板中直接察看日志&#xff0c;点击右上角黄色标志物可以打开日志面板&#xff0c;再次点击收起。 可见&…

react 升级

1、查看react版本 当前开发项目的react版本从哪里看呢&#xff1f;其实就在package.json文件中&#xff0c;搜索"react"&#xff0c;即可看到版本号 2、输入命令npm info react查看最新的react版本 3、执行命令 npm install --save react18.2.0 react-dom18.2.0 4…

Python中退出While循环的三种方法举例

Python中退出While循环的三种方法举例 在Python学习及编程应用中&#xff0c;常会使用while循环&#xff0c;对while循环条件设置不当可能导致进入死循环&#xff0c;本文将举例说明三种退出while循环的方法。 1.直接使用input函数 利用input函数使得输入值传递到while之后的…

使用jQuery的ajax提交图片信息

1 设置图片id&#xff08;html&#xff09; 首先&#xff0c;定义上传图片的id&#xff0c;根据上传文件的id获取图片信息&#xff1a; 注&#xff1a;图片的id应该设置在input标签里面 2 发送ajax请求&#xff08;js&#xff09; var formData new FormData(); formData.ap…

Hue编辑器命令执行

每一代人都有自己的命中注定的遗憾。遗憾&#xff0c;深深的遗憾。 唯一能自慰的是&#xff0c;我们曾真诚而充满激情地在这个世界上生活过&#xff0c;竭尽全力地劳动过&#xff0c; 并不计代价地将自己的血汗献给了不死的人类之树。 漏洞描述 Hue编辑器存在命令执行漏洞&am…

24种人格力量,好奇心的力量以及特征分析

人格力量是一种可支配的价值观&#xff0c;它能让人向往美好的远景&#xff0c;极大地促进人的工作发展。via认为好奇心是人格力量的种类之一。 借助via 24种人格力量测试&#xff0c;探索人格优势&#xff0c;可以帮助我们更好的发现自身的优势&#xff0c;发挥自己的潜能。从…

Sui x KuCoin Labs夏季黑客松第五批入围项目公布

经过40多天积极的报名以及精心的选拔&#xff0c;Sui x KuCoin Labs夏季黑客松现已完成对所有报名项目的筛选&#xff0c;最后一轮入围结果也在众人的期待中新鲜出炉。 了解入围项目的详细信息&#xff1a;https://hack.sui.io/demo-projects/入围项目的中文版介绍&#xff1a…

Java线程状态与状态转换

前言 在Java中&#xff0c;线程是多任务处理的基本单位&#xff0c;它可以并行执行多个任务。线程的状态描述了线程在其生命周期中的不同阶段。Java线程的状态可以分为以下几种&#xff1a; 线程状态 状态解释新建状态&#xff08;New&#xff09;线程被创建但尚未启动就绪状…