GuavaCacheUtil包

2023-10-30

package com.book.common.util;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;

/**
 * Description: 默认失效时间为10分钟,当缓存时间不为默认时间时,需要使用KEY,
 * HashKey+失效时间作为一个新的缓存数据,查询等操作也需要使用key和HashKey
 *
 * @Author: leo.xiong
 * @CreateDate: 2019/10/14 17:45
 * @Email: leo.xiong@suyun360.com
 * Version:1.0
 */
@Slf4j
public class GuavaCacheUtil {
    /**
     * 缓存项最大数量
     */
    private static final long GUAVA_CACHE_SIZE = 100000;
    /**
     * 缓存时间:毫秒
     */
    private static final long GUAVA_CACHE_TIME = 600000;
    /**
     * 并发级别,同时写缓存的线程个数
     */
    public static final int CONCURRENCY_LEVEL = 8;
    /**
     * 容器的初始值大小
     */
    public static final int INITIAL_CAPACITY = 10;

    /**
     * 缓存操作对象
     */
    private static LoadingCache<String, Object> GLOBAL_CACHE = null;

    private final static Map<String, LoadingCache<String, Object>> ALL_GLOBAL_CACHE = Maps.newHashMap();

    static {
        GLOBAL_CACHE = buildLoadingCache(GUAVA_CACHE_SIZE, GUAVA_CACHE_TIME);
    }

    private static <K, V> LoadingCache<K, V> buildLoadingCache(Long maximumSize, Long expireAfterAccess) {
        try {
            return (LoadingCache<K, V>) loadCache(new CacheLoader<String, Object>() {
                @Override
                public Object load(String key) throws Exception {
                    /**
                     * 该方法主要是处理缓存键不存在缓存值时的处理逻辑
                     */
                    if (log.isDebugEnabled()) {
                        log.debug("Guava Cache缓存值不存在,初始化空值,键名:{}", key);
                    }
                    return ObjectUtils.NULL;
                }
            }, maximumSize, expireAfterAccess);
        } catch (Exception e) {
            log.error("初始化Guava Cache出错", e);
        }
        return null;
    }

    /**
     * 全局缓存设置
     * <ul>
     * <li>缓存项最大数量:100000</li>
     * <li>缓存有效时间(分钟):10</li>
     * </ul>
     *
     * @param cacheLoader
     * @return
     * @throws Exception
     */
    private static <K, V> LoadingCache<K, V> loadCache(CacheLoader<K, V> cacheLoader, Long maximumSize, Long expireAfterAccess) throws Exception {
        /*
         * maximumSize 缓存池大小,在缓存项接近该大小时, Guava开始回收旧的缓存项 expireAfterAccess 表示最后一次使用该缓存项多长时间后失效 removalListener 移除缓存项时执行的逻辑方法 recordStats 开启Guava Cache的统计功能
         */
        LoadingCache<K, V> cache = CacheBuilder.newBuilder().initialCapacity(INITIAL_CAPACITY).maximumSize(maximumSize).expireAfterAccess(expireAfterAccess, TimeUnit.MILLISECONDS)
                .removalListener(removalNotification -> {
                    if (log.isDebugEnabled()) {
                        log.debug("Guava Cache缓存回收成功,键:{}, 值:{}", removalNotification.getKey(), removalNotification.getValue());
                    }
                }).recordStats().concurrencyLevel(CONCURRENCY_LEVEL).build(cacheLoader);
        return cache;
    }

    /**
     * 设置缓存值
     *
     * @param key
     * @param value
     */
    public static void put(String key, Object value) {
        try {
            GLOBAL_CACHE.put(key, value);
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
            }
        } catch (Exception e) {
            log.error("设置缓存值出错", e);
        }
    }

    private static LoadingCache<String, Object> getLoadCache(String key, Long expireTime) {
        LoadingCache<String, Object> cacheLoadCache = ALL_GLOBAL_CACHE.get(key);
        if (cacheLoadCache == null) {
            cacheLoadCache = buildLoadingCache(GUAVA_CACHE_SIZE, expireTime);
            ALL_GLOBAL_CACHE.put(key, cacheLoadCache);
        }
        return cacheLoadCache;
    }


    /**
     * 失效时间秒不为默认时间10分钟的
     *
     * @param key        大KEY,一般为模块信息
     * @param hashKey    查询的KEY
     * @param value      值
     * @param expireTime 失效时间(单位秒)
     */
    public static void put(String key, String hashKey, Object value, Long expireTime) {
        try {
            getLoadCache(key, expireTime).put(hashKey, value);
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(key), getAverageLoadPenalty(key));
            }
        } catch (Exception e) {
            log.error("设置缓存值出错", e);
        }
    }

    /**
     * 批量设置缓存值
     *
     * @param map
     */
    public static void putAll(Map<? extends String, ? extends Object> map) {
        try {
            GLOBAL_CACHE.putAll(map);
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
            }
        } catch (Exception e) {
            log.error("批量设置缓存值出错", e);
        }
    }

    /**
     * 批量设置缓存值
     *
     * @param map
     */
    public static void putAll(String key, Map<? extends String, ? extends Object> map, Long expireTime) {
        try {
            getLoadCache(key, expireTime).putAll(map);
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(key), getAverageLoadPenalty(key));
            }
        } catch (Exception e) {
            log.error("批量设置缓存值出错", e);
        }
    }

    /**
     * 获取缓存值
     * <p>注:如果键不存在值,将调用CacheLoader的load方法加载新值到该键中</p>
     *
     * @param key
     * @return
     */
    public static Object getIfNotPresentLoad(String key) {
        Object obj = null;
        try {
            obj = GLOBAL_CACHE.get(key);
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
            }
        } catch (Exception e) {
            log.error("获取缓存值出错", e);
        }
        return obj;
    }

    public static <T> T getIfNotPresentLoad(String key, Class<T> clazz) {
        Object obj = getIfNotPresentLoad(key);
        return obj == null ? null : (T) obj;
    }

    public static Object getIfNotPresentLoad(String key, String hashKey) {
        Object obj = null;
        try {
            if (ALL_GLOBAL_CACHE.get(key) == null) {
                return obj;
            }
            obj = ALL_GLOBAL_CACHE.get(key).get(hashKey);
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(key), getAverageLoadPenalty(key));
            }
        } catch (Exception e) {
            log.error("获取缓存值出错", e);
        }
        return obj;
    }

    public static <T> T getIfNotPresentLoad(String key, String hashKey, Class<T> clazz) {
        Object obj = getIfNotPresentLoad(key, hashKey);
        return obj == null ? null : (T) obj;
    }

    /**
     * 获取缓存值
     * <p>注:如果键不存在值,将直接返回 NULL</p>
     *
     * @param key
     * @return
     */
    public static Object get(String key) {
        Object obj = null;
        try {
            obj = GLOBAL_CACHE.getIfPresent(key);
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
            }
        } catch (Exception e) {
            log.error("获取缓存值出错", e);
        }
        return obj;
    }

    public static <T> T get(String key, Class<T> clazz) {
        Object obj = get(key);
        return obj == null ? null : (T) obj;
    }

    public static Object get(String key, String hashKey) {
        Object obj = null;
        try {
            if (ALL_GLOBAL_CACHE.get(key) == null) {
                return null;
            }
            obj = ALL_GLOBAL_CACHE.get(key).getIfPresent(hashKey);
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(key), getAverageLoadPenalty(key));
            }
        } catch (Exception e) {
            log.error("获取缓存值出错", e);
        }
        return obj;
    }

    public static <T> T get(String key, String hashKey, Class<T> clazz) {
        Object obj = get(key, hashKey);
        return obj == null ? null : (T) obj;
    }


    /**
     * 移除缓存
     *
     * @param key
     */
    public static void remove(String key) {
        try {
            GLOBAL_CACHE.invalidate(key);
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
            }
        } catch (Exception e) {
            log.error("移除缓存出错", e);
        }
    }

    public static void remove(String key, String hashKey) {
        try {
            if (ALL_GLOBAL_CACHE.get(key) == null) {
                return;
            }
            ALL_GLOBAL_CACHE.get(key).invalidate(hashKey);
            if (ALL_GLOBAL_CACHE.get(key).size() == 0) {
                ALL_GLOBAL_CACHE.remove(key);
            }
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(key), getAverageLoadPenalty(key));
            }
        } catch (Exception e) {
            log.error("移除缓存出错", e);
        }
    }

    /**
     * 批量移除缓存
     *
     * @param keys
     */
    public static void removeAll(Iterable<String> keys) {
        try {
            GLOBAL_CACHE.invalidateAll(keys);
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
            }
        } catch (Exception e) {
            log.error("批量移除缓存出错", e);
        }
    }

    public static void removeAll(String key, Iterable<String> keys) {
        try {
            if (ALL_GLOBAL_CACHE.get(key) == null) {
                return;
            }
            ALL_GLOBAL_CACHE.get(key).invalidateAll(keys);
            if (ALL_GLOBAL_CACHE.get(key).size() == 0) {
                ALL_GLOBAL_CACHE.remove(key);
            }
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(key), getAverageLoadPenalty(key));
            }
        } catch (Exception e) {
            log.error("批量移除缓存出错", e);
        }
    }

    /**
     * 清空所有缓存
     */
    public static void removeAll() {
        try {
            GLOBAL_CACHE.invalidateAll();
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
            }
        } catch (Exception e) {
            log.error("清空所有缓存出错", e);
        }
    }

    public static void removeAll(String key) {
        try {
            if (ALL_GLOBAL_CACHE.get(key) == null) {
                return;
            }
            ALL_GLOBAL_CACHE.get(key).invalidateAll();
            ALL_GLOBAL_CACHE.remove(key);
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(key), getAverageLoadPenalty(key));
            }
        } catch (Exception e) {
            log.error("清空所有缓存出错", e);
        }
    }

    /**
     * 获取缓存项数量
     *
     * @return
     */
    public static long size() {
        long size = 0;
        try {
            size = GLOBAL_CACHE.size();
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
            }
        } catch (Exception e) {
            log.error("获取缓存项数量出错", e);
        }
        return size;
    }

    public static long size(String key) {
        long size = 0;
        try {
            if (ALL_GLOBAL_CACHE.get(key) == null) {
                return size;
            }
            size = ALL_GLOBAL_CACHE.get(key).size();
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(key), getAverageLoadPenalty(key));
            }
        } catch (Exception e) {
            log.error("获取缓存项数量出错", e);
        }
        return size;
    }

    /**
     * 把缓存数据转换为Map对象
     *
     * @return
     */
    public static Map<String, Object> valueToMap() {
        ConcurrentMap<String, Object> valueMap = Maps.newConcurrentMap();
        try {
            valueMap = GLOBAL_CACHE.asMap();
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
            }
        } catch (Exception e) {
            log.error("获取所有缓存项的键出错", e);
        }
        return valueMap;
    }

    /**
     * 把缓存数据转换为Map对象
     *
     * @return
     */
    public static Map<String, Object> valueToMap(String key) {
        ConcurrentMap<String, Object> valueMap = Maps.newConcurrentMap();
        try {
            if (ALL_GLOBAL_CACHE.get(key) == null) {
                return valueMap;
            }
            valueMap = ALL_GLOBAL_CACHE.get(key).asMap();
            if (log.isDebugEnabled()) {
                log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(key), getAverageLoadPenalty(key));
            }
        } catch (Exception e) {
            log.error("获取所有缓存项的键出错", e);
        }
        return valueMap;
    }

    /**
     * 缓存命中率
     *
     * @return
     */
    public static double getHitRate() {
        return GLOBAL_CACHE.stats().hitRate();
    }

    public static double getHitRate(String key) {
        return ALL_GLOBAL_CACHE.get(key) == null ? 0D : ALL_GLOBAL_CACHE.get(key).stats().hitRate();
    }

    /**
     * 加载新值的平均时间,单位为纳秒
     *
     * @return
     */
    public static double getAverageLoadPenalty() {
        return GLOBAL_CACHE.stats().averageLoadPenalty();
    }

    public static double getAverageLoadPenalty(String key) {
        return ALL_GLOBAL_CACHE.get(key) == null ? 0D : ALL_GLOBAL_CACHE.get(key).stats().averageLoadPenalty();
    }

    /**
     * 缓存项被回收的总数,不包括显式清除
     *
     * @return
     */
    public static long getEvictionCount() {
        return GLOBAL_CACHE.stats().evictionCount();
    }

    public static long getEvictionCount(String key) {
        return ALL_GLOBAL_CACHE.get(key) == null ? 0L : ALL_GLOBAL_CACHE.get(key).stats().evictionCount();
    }
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GuavaCacheUtil包 的相关文章

  • flutter 实现消息提醒弹窗

    现在做了类似QQ的消息样式 弹窗消失 就显示创建对象 弹窗不消失就用eventbus刷新数据 重置时间五秒消失 true可以显示 false不可以显示 当点击第一个tab时false 当聊天界面返回用户ID是上面ID返回false 当退出聊
  • 小女生的Linux技术~~~Linux面试题汇总答案~~

    一 填空题 1 在Linux系统中 以 文件 方式访问设备 2 Linux内核引导时 从文件 etc fstab 中读取要加载的文件系统 3 Linux文件系统中每个文件用 i节点 来标识 4 全部磁盘块由四个部分组成 分别为引导块 专用块
  • Webpack打包之坑 _ webpackChunkName【魔法注释】

    目录 事件起因 百度查阅 webpackChunkName 结束了 事件起因 蒽 起因是这样的 项目从最初的使用 vue cli 脚手架搭建了一个初始化空架子之后就开始写项目了 也就是在刚开始的一段时间里偶尔有过几次打包查看 那时候还是能够
  • 四:SVM

    硬间隔最大化SVM SVM 介绍 SVM转化为最优解问题 KKT KKT图解 KKT定理 KKT例子 求解SVM最优化问题 拉格朗日对偶 拉格朗日对偶例子 用拉格朗日对偶解决问题 KKT在SVM中的意义 测试 SVM 介绍 SVM是一种分类
  • [Leetcode] 2. 两数相加

    题目描述 给定两个非空链表来表示两个非负整数 位数按照逆序方式存储 它们的每个节点只存储单个数字 将两数相加返回一个新的链表 你可以假设除了数字 0 之外 这两个数字都不会以零开头 示例 输入 2 gt 4 gt 3 5 gt 6 gt 4
  • 在 Linux 中配置 IPv4 和 IPv6 地址详解

    概要 IPv4和IPv6是Internet上常用的两种IP地址协议 在Linux系统中 您可以通过配置网络接口来设置IPv4和IPv6地址 本文将详细介绍如何在Linux中配置IPv4和IPv6地址 步骤 1 确定网络接口 在开始配置IP地
  • 视频监控安防平台-国标28181(GB28181)平台通过http请求获取rtsp地址再通过rtsp请求视频(HTTP服务转GB28181)

    视频监控安防平台 国标28181 GB28181 平台通过http请求获取rtsp地址再通过rtsp请求视频 HTTP服务转GB28181 最近在整理一些小型平台的功能 由原来的GB28181 RTSP小型平台改造成http服务 rtsp服
  • (小白学java)Java 变量类型

    Java 变量类型 Java 局部变量 实例变量 类变量 静态变量 int a b c 声明三个int型整数 a b c int d 3 e 4 f 5 声明三个整数并赋予初值 byte z 22 声明并初始化 z String s run
  • UNIX中文件权限与目录权限

    如下是UNIX系统中目录权限和文件权限的含义 TABLE 1 UNIX DIRECTORY Permissions WHO WHAT THE PERMISSIONS ALLOW USER Read r The account owner c
  • 短信验证功能、邮箱验证功能

    发送短信 需要借助第三方平台来发送短信 如阿里云 云通讯 对python3不友好 腾讯云 在这里用的是腾讯云来作为示例 腾讯云中短信准备工作 1 腾讯云官网注册 实名认证 登录 不废话 跳过 2 点击页面右上角 控制台 3 点击导航栏的云产
  • 初识直方图均衡化

    各位大家好 我是灿视 今天是一篇传统图像处理 直方图均衡 直方图均衡化 可以对在不同的光线条件下拍摄不同的图片进行均衡化处理 使得这些图片具有大致相同的光照条件 因此 我们可以用在训练模型之前 对图像进行对预处理 直方图均衡 1 直方图与对
  • OpenCV绘制透明底的图片,简单易懂讲解alpha通道怎么用

    今天忽然想做抠图和图形绘制 那这里就涉及到一个透明底的问题 OpenCV是很强大的 但是网上大多教程并没有讲清楚 alpha 通道的参数怎么设置 首先我们来看最简单的非 alpha 通道代码 import numpy as np impor
  • 快速开始 PieCloudDB Database:数据实例演示

    新一代云原生虚拟数仓 PieCloudDB 云上云 版 Cloud on Cloud 已于 2023 年 3 月14日重磅发布 本篇博客将从导入数据 结合虚拟电商销售数据等实例 详细展示查询计算和查询历史等功能 引导您快速了解和上 PieC
  • redis实战篇之导入黑马点评项目

    1 搭建黑马点评项目 链接 https pan baidu com s 1Q0AAlb4jM 5Fc0H RYUX A pwd 6666 提取码 6666 1 1 首先 导入SQL文件 其中的表有 tb user 用户表 tb user i
  • [cmake命令笔记]target_compile_options

    编译basalt时碰到这个命令 basalt使用的第三方库pangolin老是报错 CMake Error at thirdparty CMakeLists txt 67 target compile options Cannot spec
  • javascript 、Jquery 拆分字符串

    这是小白比较常见的问题了 比较简单就直接上代码吧 1 原生 javascript 方式 var stringObject Hello World var string stringObject split 按 一个空格 拆分字符串 cons
  • 目标检测网络:深入理解端到端的网络

    目标检测 简单来讲 就是在训练时候直接输入数据集 得到mAP 不需要关心专门训练的 相当于黑箱操作 这就是端到端的训练 不需要手工处理数据 全都封装在网络模型中 测试时 输入图像 直接得到检测结果 贴一下知乎的解答 更多更详细 https
  • 移动端专项测试

    adb命令 稳定性monkey 内存使用情况 cpu使用情况 电量消耗 流畅度 流量消耗 弱网测试 弱网延迟测试 开源工具 SoloPi 阿里开源 GT腾讯开源已经不更新了 各个指标 横向对比 纵向对比 ADB Android调试桥 And
  • 达观杯_构建模型(一)linearSVM

    特征 tfidf word tfidf article 1 特征 tfidf word tfidf article 2 模型 linearsvm 3 参数 C 5 from sklearn svm import LinearSVC 支持向量

随机推荐

  • 长方形有多少条线段_二年级数学数线段问题:找到规律,快速数线段

    1条基本线段 就是只有一条线段 2条基本线段组成的线段 有2 1 3条 3条基本线段组成的线段 有3 2 1 6条 4条基本线段组成的线段 有4 3 2 1 10条 5条基本线段组成的线段 有5 4 3 2 1 15条 数线段的原则 先1个
  • React - setState 更新状态的两种写法

    React setState 更新状态的两种写法 一 对象式的 setState 二 函数式的 setState 三 对象式的setState 对比 函数式的 setState 四 一个 setState 使用组件实例 setState 将
  • Jenkins的三种启动方式

    前置条件 Java 8环境 参考 点击查看 所有 docker环境 下载 第二种 Apache Tomcat环境 下载 第三种 一 war包启动 下载Jenkins的war包 打开终端命令行 找到war所在的路径运行java jar jen
  • blfs:为lfs虚拟机增加桌面02

    参考书籍 BLFS11 3 LFS11 3 这里面有软件安装的详细说明 树莓派Linux操作系统移植 这里面有桌面系统的脉络梳理 参考视频 https www youtube com watch v cavxyXBgJ6Q list PLy
  • 使用OLED0561制作一个视频播放器

    使用OLED屏制作视频播放器 原帖地址 使用OLED0561制作一个视频播放器 CAWCAW的意思是鸦叫声 Guaik的Logo是一只长相奇特的乌鸦 https caw guaik io d 22 oled0561 在学习完USART串口
  • 常用工具类

    目录 0 快捷键 1 对象判空 2 java 8 对象判空 抛异常 Optional ofNullable orElseThrow 3 字符串判空 4 分割字符串 5 java 8 新特性 5 1 基本形式 5 2 数组转为流 Arrays
  • 苹果CMS采集工具

    苹果CMS采集 是苹果CMS影视站必不可少的功能 现在很多站长想做一个自己的影视站点 感觉影视站点的流量很大 关键词多 做起来会非常容易 的确是这样 这篇文章主要是给大家分享一下关于影视站以及苹果CMS采集的 下面会跟大家讲解到 根据一位多
  • C#中DataGridView编辑状态控制

    DataGridView的编辑状态可以根据需求任意设置 1 设置 DataGridView1为只读dgv ReadOnly true 此时 用户的新增行操作和删除行操作也被屏蔽了 2 设置 DataGridView的第n列整列单元格为只读d
  • LeetCode题目笔记——1759. 统计同构子字符串的数目

    文章目录 题目描述 题目难度 中等 方法一 数学 代码 C 代码 Python 总结 题目描述 给你一个字符串 s 返回 s 中 同构子字符串 的数目 由于答案可能很大 只需返回对 109 7 取余 后的结果 同构字符串 的定义为 如果一个
  • zz 主要分类方法介绍

    没搜到出处 看起来应该是某本书上的 总结的还不错 2 4 1 主要分类方法介绍解决分类问题的方法很多 40 42 单一的分类方法主要包括 决策树 贝叶斯 人工神经网络 K 近邻 支持向量机和基于关联规则的分类等 另外还有用于组合单一分类方法
  • python OpenCV-Python 基础教程

    e feefe1 读取图片 import cv2 as cv 读取图片 img cv imread D MyHappy mycv2 tangmu webp 灰度转换 gray img cv cvtColor img cv COLOR BAY
  • 2.5Qt基础控件之显示控件组

    2 5Qt基础控件之显示控件组 文章目录 2 5Qt基础控件之显示控件组 总体 2 5 1QLabel标签 一 QLabel标签是什么 二 使用步骤 1 创建QLabel示例 2 QLabel标签常用的成员函数 三 示例 模范qq登录界面设
  • join()方法是否会释放锁?

    众所周知 join 方法底层调用了wait 方法 那么wait 方法明明是会释放锁的 为什么会有join是否释放锁的这个问题出现呢 原因是因为join 方法只会释放内部锁 自己方便的叫法 不会释放外部锁 自己方便的叫法 废话不多说 上代码
  • 大数据毕业设计项目-选题建议

    文章目录 0 前言 1 如何选题 1 1 选题技巧 如何避坑 重中之重 1 2 为什么这么说呢 1 3 难度把控 1 4 题目名称 1 5 最后 2 大数据 选题推荐 2 1 大数据挖掘类 2 2 大数据处理 云计算 区块链 毕设选题 2
  • Claude: ChatGPT替代大语言模型

    产品介绍 Claude是Anthropic推出的类ChatGPT大语言模型 也是一个AI人工智能助理 可以帮助各种行业的用户处理工作 如客户服务 法律 教练 搜索和销售 Claude可以通过聊天界面和API进行访问 能够完成各种对话和文本处
  • 2023年Python面试题_Python进阶_48道

    Python 中类方法 类实例方法 静态方法有何区别 类方法 是类对象的方法 在定义时需要在上方使用 classmethod 进行装饰 形参为 cls 表示类对象 类对象和实例对象都可调用 类实例方法 是类实例化对象的方法 只有实例对象可以
  • 【夜莺监控搭建】

    夜莺监控搭建V6版本 v6版本系统架构 安装部署 安装时序数据库 安装mysql redis和n9e 夜莺主程序 安装categraf 登录平台 如何修改密码 添加数据源 官网 https flashcat cloud GitHub项目地址
  • 【云原生之Docker实战】使用Docker部署Linkstack链接共享平台

    云原生之Docker实战 使用Docker部署Linkstack链接共享平台 一 Linkstack介绍 二 本地环境介绍 2 1 本地环境规划 2 2 本次实践介绍 三 本地环境检查 3 1 检查Docker服务状态 3 2 检查Dock
  • 【解决】spring-xxx-xxx-0.0.1-SNAPSHOT.jar中没有主清单属性完美解决

    这种情况就是因为没有在SpringBoot中pom文件安装maven plugin 导致出现没有主清单属性问题
  • GuavaCacheUtil包

    package com book common util import com google common cache CacheBuilder import com google common cache CacheLoader impo