设计模式-创建型-简单工厂模式(SimpleFactory)
参考文献
https://java-design-patterns.com/patterns/factory/
https://www.oodesign.com/factory-pattern
简单工厂模式
也称为简单工厂(Simple Factory)或静态工厂方法(Static Factory Method)
创建对象而不向客户端公开实例化逻辑。
通过公共接口引用新创建的对象
简单工厂模式通过一个工厂类来创建不同类型的对象,客户端只需要给工厂传入相应的参数,由工厂来根据参数判断要创建哪一种对象,并返回该对象给客户端使用。简单工厂模式的核心是工厂类,它负责创建对象。
组件
产品接口(Product Interface)
工厂类(Factory Class)
具体产品(Concrete Product Class)
具体实现
12345678910111213141516171819202122public class VideoFactory { public Video getVideo(String type) { switch (type) & ...
解决方案-限流器
参考文献
我司用了 6 年的 Redis 分布式限流器,可以说是非常厉害了!
限流的原理以及常用算法
关于两种限流模式
限流的目的
高并发系统中有三把利器用来保护系统:缓存,降级和限流.限流的目的是为了保护系统不被大量请求冲垮,限制系统的输入和输出流量已达到保护系统的目的.在电商的秒杀活动中,限流是必不可少的一个环节.
常见的限流算法有:令牌桶、漏桶.计数器也可以进行限流实现.
令牌桶
令牌桶算法是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌.可以控制流量也可以控制并发量,假如我们想要控制 API 网关的并发量最高为 1000,可以创建一个令牌桶,以固定的速度往桶里添加令牌,超出了 1000 则不添加.
当一个请求到达之后就从桶中获取一个令牌,如果能获取到令牌就可以继续往下请求,获取不到就说明令牌不够,并发量达到了最高,请求就被拦截.
漏桶
漏桶是一个固定容量的桶,按照固定的速率流出,可以以任意的速率流入到漏桶中,超出了漏桶的容量就被丢弃,总容量是不变的.但是输出的速率是固定的,无论你上面的水流入的多快,下面的出口只有这么大,就像水坝开闸放水一样
常见的 ...
解决方案-延时队列
参考文献
一口气说出 6种 延时队列的实现方法,面试官也得服
延时队列常用实现详解
你真的知道怎么实现一个延迟队列吗 ?
Redisson源码(二)延迟队列RDelayedQueue的使用及原理分析
延时队列的定义
首先队列是一种先进先出(FIFO)的数据结构.普通队列中的元素是有序的,先进入队列的元素会被优先取出进行消费.延时队列相对普通队列最大的区别是在于其"延时"的特性上.
普通队列的元素是先进先出,是按照队列入队的顺序进行处理;延时队列中的元素会指定一个延时时间,表示其希望在经过指定时间后再进行处理.
延时队列的使用场景
新建的订单,如果用户在 15 分钟内未支付,则自动取消.
公司的会议预定系统,在会议预定成功后,会在会议开始前半小时通知所有预定该会议的用户.
安全工单超过 24 小时未处理,则自动拉企业微信群提醒相关责任人.
用户下单外卖以后,距离超时时间还有 10 分钟时提醒外卖小哥即将超时.
延时队列的具体实现方案
Java DelayQueue
DelayQueue是无界的延时阻塞队列,内部是使用优先级队列PriorityQueue ...
SpringMVC-过滤器,拦截器,监听器
参考文献
一口气说出 过滤器 和 拦截器 6个区别,别再傻傻分不清了
实习生:拦截器和过滤器有啥区别?
过滤器(Filter)
作用:过滤器是处于客户端和服务器资源文件之间的一道过滤网,帮助我们过滤掉一些不符合要求的请求,通常用作Session校验,判断用户权限,如果不符合设定条件,则会被拦截到特殊的地址或者基于特殊的响应。
过滤器的使用
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869package com.holelin.sundry.filter;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet ...
SpringBoot-日志切面
参考文献
又被逼着优化代码,这次我干掉了出入参 Log日志
注解
123456789101112131415161718192021222324252627282930package com.holelin.sundry.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * @Description: * @Author: HoleLin * @CreateDate: 2022/1/12 2:37 PM * @UpdateUser: HoleLin * @UpdateDate: 2022/1/12 2:37 PM * @UpdateRemark: 修改内容 * @Version: 1.0 */@Target( ...
Java并发源码分析-AbstractQueuedSynchronizer源码分析
参考文献
万字超强图文讲解AQS以及ReentrantLock应用(建议收藏)
<<Java并发编程艺术>>
AbstractQueuedSynchronizer
队列同步器,简称同步器或AQS
AQS可重写的方法
方法名称
方法描述
protected boolean tryAcquire(int arg)
独占式获取同步状态
protected boolean tryRelease(int arg)
独占式释放同步状态
protected int tryAcquireShared(int arg)
共享式获取同步状态返回值>=0表示获取成功,反之获取失败
protected boolean tryReleaseShared(int arg)
共享式释放同步状态
protected boolean isHeldExclusively()
当前同步器是否在独占模式下被线程使用,一般该方法表示是否被当前线程独占.
同步状态指的是有volatile修饰的state变量,涉及的相关方法
方法名称
方法描述 ...
Java并发编程(七)-Java内存模型(JMM)
参考文献
<<Java并发编程艺术>>
<<深入理解Java虚拟机-JVM高级特性与最佳实践>>
JSR 133 (Java Memory Model) FAQ
The Java Memory Model
【死磕Java并发】-----Java内存模型之happens-before
The JSR-133 Cookbook for Compiler Writers
Java内存模型(JMM)
The Java memory model describes how threads in the Java programming language interact through memory. Together with the description of single-threaded execution of code, the memory model provides the semantics of the Java programming language. --Wikipedia
Java内存模型描述了Java编程 ...
Java并发编程(六)-Java并发机制的底层实现原理-原子操作
参考文献
<<Java并发编程艺术>>
<<Java语言规范-基于Java SE 8>>
原子操作的实现原理
在Java中可以通过锁和循环CAS的方式来实现原子操作;
使用循环CAS实现原子操作
JVM中CAS操作是利用处理器提供的CMPXCHG指令实现的.自旋CAS实现的基本思路就是循环进行CAS操作直到成功为止.
1234for(;;){ int i = atomicI.get(); boolean sunc= atomicI.compareAndSet(i,i++);}
CAS实现原子操作的三大问题
ABA问题
因为CAS需要在操作值的时候,检查值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时就会发现它的值没有发生变化,但是实际上变化了.
ABA问题的解决思路就是用版本号.在变量前面追加版本号,每次变量更新的时候把版本号加1,那么由原来的A->B->A变成了1A->2B->3A.
从JDK5开始 ...
Java并发编程五-Java并发机制的底层实现原理-synchronized
参考文献
<<Java并发编程艺术>>
<<Java语言规范-基于Java SE 8>>
http://www.itabin.com/synchronized-lock/
引言
Java编程语言提供了多种用于线程通信的机制.这些方法中最基础的就是同步(synchronization),它是使用监视器(monitor)实现的.Java中每个对象都与一个线程可以锁定或解锁的监视器相关联.在任何时刻,只有一个线程可以持有某个监视器上的锁.任何其他试图锁定该监视器线程都将阻塞,直到它们可以获得该监视器上的锁.
线程T可以多次锁定某个特定的监视器,而每个解锁操作都会抵消一次锁定操作的效果.(可重入锁)
synchronized
synchronized语句是对对象的引用,即基于对象实现,然后它试图执行在该对象的监视器上的锁定动作,并且在锁定动作成功完成之前,不会执行下一步动作.在锁定动作执行之后,synchronized语句体被执行.如果该语句体执行结束,无论是正常结束还是异常结束,都会在相同的监视器上执行解锁动作.
syn ...
Java并发编程(四)-Java并发机制的底层实现原理-volatile
参考文献
<<Java并发编程艺术>>
<<Java语言规范-基于Java SE 8>>
CPU高速缓存行与内存关系 及并发MESI 协议
[死磕 Java 并发] — Java内存模型之分析volatile
volatile
CPU术语
术语
英文
描述
内存屏障
memory barrier
是一组处理器指令,用于实现对内存操作的顺序限制
缓存行
cache line
缓存中可以分配的最小存储单位.处理器填写缓存行时会加载整个缓存行,需要使用多个主内存读周期
原子操作
atomic operations
不可中断的一个或一系列操作
缓存行填充
cache line fill
当处理器识别到从内存中读取操作数是可缓存的,处理器读取整个缓存行到适当的缓存(L1,L2,L3的或所有)
缓存命中
cache hit
如果进行高速缓存行填充操作的内存位置仍然是下次处理器访问的地址时,处理器从缓存中读取操作数,而不是内存读取
写命中
write hit
当处理器将操作数写回到一个内存缓存的区域时,它首先会检 ...