导图社区 Java全栈知识
这是一篇关于Java全栈知识的思维导图,主要内容有Java基础、JVM、Spring、Mybatis、Redis、RocketMQ。
编辑于2022-08-06 09:29:04 广东Java全栈知识
Java基础
面向对象编程
封装
继承
多态
泛型
集合
多线程
创建线程方式
线程状态和通信
wait()/notify()
wait(): 立即释放锁
notify: 临界区的代码执行完才释放锁
子主题
虚假唤醒
总结
调用notify/notifyall 不会立即释放锁,而是执行完临界区代码后才释放锁
线程池
核心参数
拒绝策略
新建线程池方式
线程池发生死锁的原因
JUC
AQS原理
概念:AQS是框架。是信号量、ReentranLock、DownLoad等工具类的一个底层。
state
stat使用volatile来修饰
如果是独占锁,state的值为0表示初始状态没有加锁,>0表示同一个线程重入次数
如果是共享锁,表示同时能给多少个线程加锁
一般使用CompareandSetState()这个方法来设置stat的值,使用的是cas乐观锁来设置这个指
等待队列
在AQS里维护这一个双端队列,当获取锁失败,会加入该队列里
条件队列
ConditionQueue,如果线程获取到锁,调用await()或者wait()会进入该队列
如果嗲用signal/signalAll notify/notifyAll 会先判断有没有等待队列有没有结点,如果有加入等待队列,如果没有 直接获取锁。
公平锁/非公平锁
公平锁和非公平锁是ReentranLock实现的。公平锁加锁的时候不会一来就尝试加锁,而是直接调用acquire(1) 方法。  公平锁直接调用acquire(1). 
AQS相关工具类
Threadlocal
双端队列
常用方法
addFirst(): 向队头插入元素,如果元素为空,则发生NPE(空指针异常) addLast(): 向队尾插入元素,如果为空,则发生NPE offerFirst(): 向队头插入元素,如果插入成功返回true,否则返回false offerLast(): 向队尾插入元素,如果插入成功返回true,否则返回false removeFirst(): 返回并移除队头元素,如果该元素是null,则发生NoSuchElementException removeLast(): 返回并移除队尾元素,如果该元素是null,则发生NoSuchElementException pollFirst(): 返回并移除队头元素,如果队列无元素,则返回null pollLast(): 返回并移除队尾元素,如果队列无元素,则返回null getFirst(): 获取队头元素但不移除,如果队列无元素,则发生NoSuchElementException getLast(): 获取队尾元素但不移除,如果队列无元素,则发生NoSuchElementException peekFirst(): 获取队头元素但不移除,如果队列无元素,则返回null peekLast(): 获取队尾元素但不移除,如果队列无元素,则返回null pop(): 弹出栈中元素,也就是返回并移除队头元素,等价于removeFirst(),如果队列无元素,则发生NoSuchElementException push(): 向栈中压入元素,也就是向队头增加元素,等价于addFirst(),如果元素为null,则发生NPE,如果栈空间受到限制,则发生IllegalStateException; add: 元素为null抛异常 offer: 返回ture/false remove:队列为空抛异常 poll: 返回元素并移除元素,队列为空返回null get: 获取元素但是不移除元素,队列为空,抛异常 peek: 获取元素,不移除元素,队列为空,返回null。 pop:压栈 push:出栈 ArrayBlockingQueue中有三对存取api,如下表所示: 操作类型 抛出异常 阻塞线程 有返回值 超时返回 存入 add put offer offer(E e, long timeout, TimeUnit unit) 取出 get/remove take poll poll(long timeout, TimeUnit unit)
子主题
Synchronize
synchronize和Reentrant区别
Synchronize: 抛异常自动释放锁; 获取锁失败一直等待; 适合少量同步,当线程对锁的竞争激烈的时候,性能会下降几十倍。 ReentrantLock: 抛异常不会自动释放锁,需要在finnal中释放; 获取锁失败,可以等待也可以根据tryLock()来判断,自己决定等不等待; 适合大量同步,性能受线程的竞争激烈程度影响不大,比较缓和;
volatile
作用1:禁止指令重排序
使用场景:单例模式双重检查锁中,其中的 单例对象要用volatile来修饰,因为new一个对象有多步,需要禁止指令重排,防止拿到的是空的对象
public class Singleton { public static volatile Singleton singleton; /** * 构造函数私有,禁止外部实例化 */ private Singleton() {}; public static Singleton getInstance() { if (singleton == null) { synchronized (singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
作用2:可见性
例子:ReentrantLock中的stat标识就是使用volatile来修饰的
作用3:保持单次操作的原子性
在32位机器上使用long,double作为共享变量来使用,要用volatile修饰
ThreadLocal
原理
ThreadLocal内部维护者一个变量,private Entry[] table; 这个map就保存了这么多个线程,以及对应的value。 当一个新的线程执行set("somevalue"),会这个table新添加一个节点元素, Entry可以理解为key=当前线程,value=具体的值;线程会有这个节点的引用。 当这个线程再次set()是,就往自己的threadlocals这个map添加就可以 。 
注意事项:
资源同步的策略
互斥锁
Synchronize,ReentranLock
非阻塞同步
乐观锁(cas)
无同步
ThreadLocal
异常
JVM
Spring
Mybatis
Redis
RocketMQ
使用场景
生产合约合同
excle文件详细导入
子主题
需要解决的问题
消息正确消费
消息重复消费(保证幂等性)
解决方法:
在消费者端,将消息的业务的唯一ID作为主键插入一个表中,表示该消息已经正常消费了。
消息丢失
解决办法:
分析可能会出现小丢失的几种情况 :  生产者向消费者发送送消息,存在网络不稳定,丢失消息; 消息主备同步的失败:如果主节点宕机后重启,还没来得及写入备份b1,就会丢失消息; 刷盘失败,如果broker挂机了后重启,就会丢失消息; 消息消费失败 ; 解决方案: 使用消费同步刷盘,保证消息正常写入日志; 如果消息消费失败会,是重试15,如果还失败,会进入死信队列,进行人工处理;
最终一致性
Zookeeper
Oracle
Mysql