代码仓库:https://github.com/Fiziluuk/JucDemo
谈谈volatile的理解
谈谈CAS compareAndSet
比较并交换
Unsafe类在sun.misc包中,调native方法像指针一样操作内存 unsafe.getAndAddInt(this, valueOffSet, 1) valueOffset是变量的内存偏移量
/*
var1 AtomicInteger对象本身
var2 该对象值的引用地址
var4 需要变动的数量
var5 通过var1和var2找到主存中的对象的属性的真实值
用该对象属性当前的值和var5进行比较
如果相同,更新var5 + var4 并且返回true
如果不同,循环继续取var5再比较,直到更新完成
*/
AtomicInteger.getAndIncrement(){
return unsafe.getAndAddInt(this, valueOffset, 1);
}
//unsafe.getAndAddInt
pulic final int getAndAddInt(Object var1, long var2, int var4){
int var5;
do{
var5 = this.getIntVolatile(var1, var2);
}while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4);
return var5;
}
CAS的底层原理是什么?如果知道,谈谈Unsafe
CAS 缺点是什么?
原子类 AtomicInteger 的 ABA 问题了解嘛?原子更新引用知道嘛?
ABA 问题:CAS 算法实现的前提时从主存取数据并在当下时刻比较并替换,在这个时间差里可能导致数据变化
原子引用(AtomicReference)
通过该类包装实体类,实现原子性
原子引用 + 修改版本号(类似时间戳)(AtomicStampedReference)
每次修改版本号变了(+1),其他线程回写时如果版本号不对,不能更新
ArrayList 是线程不安全的,写一个示例并给出解决方案。(Set 和 Map 同理)
异常信息:java.util.ConcurrentModificationException 并发修改异常 ArrayList线程不安全
导致原因:并发争抢修改导致,一个线程在写,另一个线程抢夺,导致异常
解决方案
new Vector<>();使用vector,底层加了synchronized,一般不用
Collections.synchronizedList(new ArrayList<>()) 使用List的父类提供的方法
new CopyOnWriteArrayList<>(); 使用 JUC 包中的类,写时复制:每次copy一个副本,扩容1,写入数据,将原副本的引用指向新副本(替换掉原副本),通知其他线程该资源已修改,释放锁(Reentant Lock)
HashSet 底层是HashMap,存进去的值是map的key,value 统一都是叫 PRESENT 的对象
公平锁/非公平锁/可重入锁/递归锁/自旋锁?手写一个自旋锁?
公平锁/非公平锁 new ReentrantLock(); 参数为 true 创建公平锁,为空或者 false 创建非公平锁。如果后来的线程没抢到锁,就采用公平锁方式(去排队)
可重入锁(递归锁)
自旋锁
尝试获取锁的线程不会阻塞,而是采用循环的方式去尝试获取锁,好处是减少线程上下文切换的消耗,缺点是循环会消耗 CPU。
独占锁(写锁)/共享锁(读锁)/互斥锁
CountDownLatch / CyclicBarrier / Semaphore 使用过嘛?
CountDownLatch :阻塞调用 await() 的线程,其他线程调用 countDown() 方法为计数器减1,直到计数器为0时,唤醒被 await() 阻塞的线程。
CyclicBarrier :可循环使用的屏障。一组线程到达屏障(同步点)时被阻塞,知道最后一个线程到达,所有被屏障拦截的这组线程才能继续执行。线程通过 await() 方法进入屏障。
Semaphore :(信号灯)主要用于两个目的:一是用于多个资源的互斥使用,另一个用于并发线程数的控制。
阻塞队列了解嘛?队列为空时,取元素被阻塞。队列满时,加元素被阻塞。
阻塞队列有没有优点?
阻塞队列核心方法
阻塞队列应用
生产者消费者模式:
传统版:ProdConsumer_TraditionDemo
阻塞队列版:ProdConsumer_BlockQueueDemo
线程池
消息中间件
Synchronized 和 lock 有什么区别?
不得不阻塞时如何管理?
谈谈线程池
线程池的优势
线程池如何使用
线程池的重要参数 ThreadPoolExecutor
谈谈线程池底层工作原理
拒绝策略