java

redis cache抽象实现

概述 redis缓存在项目中经常用到,如果每个需要的地方独立实现,会有各种各样的问题,如实现的功能不健壮,代码冗余 本篇的宗旨是构建一个抽象的,功能完善,代码健壮的缓存模块,使得接入时,通够快速、便捷的使用缓存 Cache redis中缓存的对象 /** * @author liuk * 封装此对象的目的 * 1. 当从redis批量获取对象时,能够清楚获取到的value对应的key * 当然redis返回时,是与请求时的key的顺序是一致的,如果未取到会返回null,通过顺序的一致性也是可以确定获取到的value对应的key的 * 2. 如果该key确实不存在对应的对象,防止一直透过缓存查数据库,故该场景保存的value=null */ @Data public class Cache&

  • 凯文
6 min read
java

java之简易bitmap实现

当需要用比较少的空间存储true和false时,不防考虑下通过bitmap实现。 bitmap用途还是非常广泛的,比如布隆过滤器等。 下面介绍如何用java实现一个bitmap用于存储状态数据(0/1、true/false) public class BitMap { /** * 二进制数据存储,存储内容为[0,0,1,1] */ char[] binaryChars = null; /** * 扩张因子,当binaryChars小时,以该值扩张 */ private static final double DILATATION_FACTOR = 1.3; /** * defaultChar

  • 凯文
2 min read

ScheduledThreadPoolExecutor 为什么不能指定maximumPoolSize

ScheduledThreadPoolExecutor不能指定maximumPoolSize,‌这是因为其内部实现机制决定的。‌ScheduledThreadPoolExecutor的构造函数中,‌maximumPoolSize参数被硬编码为Integer.MAX_VALUE,‌这意味着无论我们如何设置maximumPoolSize参数,‌其实际最大线程数始终是Integer.MAX_VALUE,‌即理论上的最大整数值。‌这种设计选择背后的原因主要是为了确保延迟任务能够及时被处理,‌避免因为线程池大小限制而导致任务处理延迟。‌ ScheduledThreadPoolExecutor使用的是DelayedWorkQueue队列,‌这是一个无界队列,‌意味着其可以容纳无限多的任务。‌由于这个队列是无界的,‌因此设置maximumPoolSize实际上是没有意义的,‌因为队列本身不会成为限制因素。‌corePoolSize参数指定了线程池中的线程数量,‌而keepAliveTime参数定义了当线程池中的线程数量超过corePoolSize时,‌多余的空闲线程的存活时间。‌然而,‌由于maximumPoolSize被设置为一个极大的值,‌实际上线程池的大小主要受控于corePoolSize的设置,‌以及任务队列的处理能力。‌ 此外,‌由于ScheduledThreadPoolExecutor主要负责调度延迟执行的任务,‌它并不直接处理业务逻辑。‌这意味着,‌即使设置了较大的corePoolSize,‌在实际应用中,‌如果并发任务较少,

  • 凯文
1 min read
mysql

mysql之自增id

自增id值的存储方式 innodb在5.8版本前是不对该值进行存储的,只是放在内存中,如果实例重启,则查询表的最大值+1,重新放在内存中。 在5.8以后会将自增值的变更记录在redo log中,重启后依靠redolog恢复重启前值。 自增id修改时机 当执行insert操作时,如果未指定id,或id为0,则会取自增id并将自增值+1;如果指定了id,则会计算指定的id与自增值的大小,如果小的话不会对自增值进行操作,如果大于自增值,则会将自增值修改为该id+1 严格来说并非+1,而是+auto_increment_increment的值 自增锁的范围 在5.1.

  • 凯文
3 min read
idea

idea启动java服务报错OutOfMemoryError: GC overhead limit exceeded解决方法

在用idea开发java项目时,启动报内存溢出错误,致服务启动失败:Error:java: java.lang.OutOfMemoryError: GC overhead limit exceeded 报此错说明启动期间内存不够用了,把idea的启动进程堆内存值设大点就行了。 设置窗口:Settings --->Build,Execution,Deployment---> Complier 把 build process heap size 值改大点即可 如下图所示: 把此值改为1000,重新启动服务正常。

  • 凯文
1 min read
geek

并发编程之限流算法

计数限流 最简单的限流算法就是计数限流了,例如系统能同时处理100个请求,保存一个计数器,处理了一个请求,计数器加一,一个请求处理完毕之后计数器减一。 每次请求来的时候看看计数器的值,如果超过阈值便拒绝处理。 非常的简单粗暴,计数器的值要是存内存中就算单机限流算法。存中心存储里,例如 Redis 中,集群机器访问就算分布式限流算法。 优点就是:简单粗暴,单机在 Java 中可用 Atomic 等原子类、分布式就 Redis incr。 缺点就是:假设我们允许的阈值是1万,此时计数器的值为0, 当1万个请求在前1秒内一股脑儿的都涌进来,这突发的流量可是顶不住的。缓缓的增加处理和一下子涌入对于程序来说是不一样的。 固定窗口限流算法

  • 凯文
4 min read
geek

并发设计模式

Immutability模式:如何利用不变性解决并发问题? Copy-on-Write模式:不是延时策略的COW 线程本地存储模式:没有共享,就没有伤害 Guarded Suspension模式:等待唤醒机制的规范实现 Balking模式:再谈线程安全的单例模式 Thread-Per-Message模式:最简单实用的分工方法 Worker Thread模式:如何避免重复创建线程? 两阶段终止模式:如何优雅地终止线程? 生产者-消费者模式:用流水线思想提高效率 Immutability模式:如何利用不变性解决并发问题? 利用 Immutability 模式解决并发问题,也许你觉得有点陌生,其实你天天都在享受它的战果。Java 语言里面的 String 和 Long、

  • 凯文
15 min read