1. thread的方法
Thread.sleep():占用cpu资源
Thread.yeild():当前线程让渡cpu资源,大家竞争,也有再抢到cpu的机会
t1.join():在t2线程中,调用t1.join(),是等待t1执行完成
2. 线程状态
3. synchronized
程序出现异常,synchronized锁默认会释放
synchronized锁的是对象,不是代码
synchronized锁的对象不能是String常量、Integer、Long
4. 单例的双重检查为什么要用volatile
因为 instance = New Singleton()
指令重排时,可能将半初始化的对象赋值给instance
5. LongAdder
LongAdder用于多线程给同一个数递增使用,内部使用分段锁,线程数越多效率越高
6. 可重入
同一个线程多次申请同一把锁时,依然可以执行
7. ReentrantLock
synchronized是自动解锁的,Lock需要手动解锁lock.unlock(finally)
ReentrantLock有一个tryLock方法,尝试获取锁
ReentrantLock可以被打断(lock.lockInterruptibly() ),synchronized不可以
ReentrantLock默认非公平锁,可以设置为公平锁:new ReentrantLock(true)
8. CountDownLatch
CountDownLatch:用于倒数,可以设置倒数值
latch.countDown() 等待数-1
latch.await() 直到等待数
9. CyclicBarrier
CyclicBarrier用于等待一定数量的线程后执行new CyclicBarrier(100,()->{});
10. Phaser
Phaser:按照不同的阶段对线程进行执行,需要重写onAdvance方法
11. ReadWriteLock:读写锁
读的时候加共享锁,其他读线程可以继续读,写线程不可以进入
写的时候加排他锁,其他线程不可以读也不可以写
12. Semaphore
可以用于限流,限制同时有多少线程执行
acquire() 获取锁
release() 释放锁
13. Exchanger
Exchanger:用于线程之间交换数据,交换数据时是阻塞的
14. LockSupport
LockSupport.park()阻塞当前线程
LockSupport.unpark(t) 继续运行t线程
unpark方法可以先于park方法调用
15. condition
Lock可以指定条件 lock.newCondition()
condition.await()方法可以让一定条件的线程wait
condition.signalAll()方法唤醒一定条件的线程
16. AQS: AbstractQueuedSynchronizer
AQS的核心是共享的state变量,volatile修饰的,通过CAS的方式给state设值;还有一个双向链表,没有获取到锁的线程通过CAS的方式加到链表的末端tail
为什么要设值成双向链表,因为后面的节点需要拿到前面的节点
17.VarHandle
变量句柄,引用,普通属性可以进行原子性操作;比反射快,可以直接操作二进制码
18.ThreadLocal
线程本地变量,线程a设值的值不影响线程b
使用完ThreadLocal后需要调用remove方法,要不然会有内存泄漏的问题
19. java的引用
分为强软弱虚
强引用:Object o = new Object();
软引用:SoftReference,当一个对象对软引用指向时,只有内存不够时,才会被垃圾回收掉
弱引用:WeakReference,只要遭遇gc就会回收,一般用于容器中,ThreadLocal的Entry使用了弱引用
虚引用:PhantomReference,虚引用被垃圾回收时会收到一个通知,可以用于NIO的直接内存清理时,发出通知清理堆外内存
( 垃圾回收的时候,会调用finlize方法,可以看到对象被回收了)
20. 为什么threadLocal的 Entry要使用弱引用?
若是强引用,即使threadLocal=null,但key的引用依然指向ThreadLocal对象,所以会有内存泄漏,而使用弱引用则不会
21. ExecutorService
ExecutorService的submit返回值是Future,线程池的返回值会存在Future中,通过get获取
22. FutureTask
FutureTask:本身既是Runnable也是Future,可以创建任务,也可以保存返回值
23. CompletableFuture
CompletableFuture可以管理一堆任务,等待全部执行结束CompletableFuture.allOf(cf1,cf2,cf3).join()
24. 默认的 ThreadPoolExecutor
Executors.newSingleThreadExecutor(): 单线程的线程池,保证任务有序执行
为什么要有单线程的线程池:方便管理线程池生命周期;阻塞队列;
Executors.newCachedThreadPool():核心线程数为0,最大线程数是int的最大值,阻塞队列是SynchronousQueue
Executors.newFixedThreadPool():固定长度
Executors.newScheduledThreadPool():用于执行定时任务,阻塞队列是DelayedWorkQueue,可以指定多久执行一次任务池任务(service.schedulAtFixedRate)
自定义拒绝策略需要实现RejectExecutionHandler
ThreadPoolExecutor的Worker
25.ForkJoinPool
ForkJoinPool:分解汇总的任务,用很少的线程可以执行很多的任务(子任务)
Executors.newWorkStealingPool():每个线程维护一个任务队列,如果某个队列执行完成,可以从其他队列中获取任务
RecursiveAction:不带返回值
RecursiveTask<T>: 带返回值
26.JMH
用于测试程序性能
27. Disruptor
Disruptor:分裂、瓦解;单线程每秒最多能处理600w任务;性能极高;CAS;单机支持高并发;底层是个环形数组