1. await——》wait,signal——》notify,signalAll——》notifyAll
- await会先释放锁,然后执行park
- park本身不释放锁
2. ConcurrentHashMap 1.7 1.8
1.7
- 底层实现是分段锁,segment一旦初始化不可扩容,默认16
- map的扩容针对的是段内的entry数组
1.8
- 底层结构和HashMap一样,分任务段给多个线程进行数据迁移
3. ConcurrentLinkedQueue HOPS延迟更新
- 当tail指向的节点的下一个节点不为null的时候,会执行定位队列真正的队尾节点的操作,找到队尾节点后完成插入之后才会通过casTail进行tail更新;当tail指向的节点的下一个节点为null的时候,只插入节点不更新tail。
- 当head指向的节点的item域为null的时候,会执行定位队列真正的队头节点的操作,找到队头节点后完成删除之后才会通过updateHead进行head更新;当head指向的节点的item域不为null的时候,只删除节点不更新head。
目的:减少大量并发写入删除操作时频繁更新头尾结点的操作
4. interruped会清除打断标记
5. 线程池
参数
-
核心线程数
-
任务/阻塞队列
-
拒绝策略
- 直接抛出异常,默认
- 由调用者线程执行
- 丢弃最前面的任务,加入当前任务
- 丢弃任务,不抛异常
-
最大线程数
-
线程空闲保持时间
- 非核心线程达到时间就会退出
-
时间单位TimeUnit
-
线程创建工厂
为什么不允许Executors创建
-
无限堆积任务,OOM
- newFixedThreadPool
- 所有线程都是核心线程,创建时设置大小
- newSingleThreadExecutor
- 核心线程和单个线程都是1,核心线程出异常就创建一个新的代替
- newFixedThreadPool
-
无限创建线程,OOM
-
newCachedThreadPool
- 所有线程都是非核心线程,均可回收
-
newScheduledThreadPool
- 初始化指定核心线程数,可用于定时任务
-
6. CountDownLatch
- 底层依靠Sync内部类(继承AQS)
- await(),countDown()
7. CyclicBarrier
- 内部类Generation,每一次使用CB都可以看作是Generation的一个实例,Generation内部Broken属性记录当前代是否被破坏
- CDL像是计数器,一个线程执行完成计数减一,阻塞主线程直到计数为0
- CB像同步器,加入一个线程(调用await())就阻塞,计数加一,阻塞的线程数达到设置的阈值,调用(runnable任务(如果设置了)),不会阻塞主线程的执行
- 执行await()会判断当前阻塞的线程数是否达到设定值,达到了还会执行nextGeneration()生成下一代,signalAll唤醒上一代阻塞的所有线程
8. Semaphore
- 信号量没有重入概念,只有10个令牌,一个线程执行11次qcquire()也会被park住
- release()能添加令牌,和初始化设置几个令牌无关,初始化10个,可以调用11次release()
9. @Contended
填充缓存行,一条CacheLine内只有需要存储的数据,解决缓存为共享问题
- CacheLine存储了a、b,一个线程修改了a,总线嗅探到之后其他线程CacheLine里有a的都需要失效,这时候b也就跟着失效了
10. Exchanger
- 解决两个线程通信的问题
- a线程向空slot插入数据,阻塞等待b线程传递数据,b线程取出指定slot的数据,再插入需要给a的数据
- 内部类Participant继承ThreadLocal,为每一个线程保留唯一的Node结点,所以每个线程都能找到自己的slot
- 在没有竞争的情况下使用单个Node结点的slot,当出现多个线程都需要交换数据(a和b,c和d)这时候就需要Node数组arena数组槽
- 不同JDK版本的实现
- 5中只有单个slot
- 6开始类似ConcurrentHashMap分段锁的思想
- SynchronousQueue是单向的,Exchanger传递两个数据,a-》b,b-》a
- 先到先得,a,b,c,d同时执行exchange(),根据实际执行的先后顺序存取存取
11. ThreadLocal
每个Thread都有一个内部类ThreadLocalMap,调用ThreadLocal.set()时实际是把这个ThreadLocal对象存入Thread内部的ThreadLocalMap中,key就是ThreadLocal(this)
- ThreadLocalMap不是Map的实现类,是内部的自实现,维护一个Entry数组
- Entry数组是弱引用的
- 当不在强应用ThreadLocal时,key会被回收,value因为是强引用所以会被保留,Java8优化,调用get()、set()、remove()时会清除掉ThreadLocalMap所有key为null的value,下一次GC会回收内存