概念
1. 进程、线程
2. 线程状态: 新创建(New),可运行(Runnable),阻塞(Blocked),等待(Waiting),计时等待(Timed Waiting),终止(Terminated)
3. 线程优先级 setPriority(Thread.MIN_PRIORITY/MAX_PRIORITY/NORM_PRIORITY),0到10,依赖系统,因为要和系统优先级做匹配
4. 守护线程 setDaemon(boolean isDaemon) 线程启动前调用,当只剩下守护线程时,虚拟机退出。
5. 未捕获异常处理器
static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler) -- 全部线程
void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler) -- 指定线程
流程: 参考java.lang.Thread#dispatchUncaughtException
1. 选择uncaughtExceptionHandler, 如果没有设置,则为ThreadGroup(实现了Thread.UncaughtExceptionHandler接口)
2. 如果有parent(也是ThreadGroup),则交给parent处理;否则如果有默认的,交给默认Handler处理;否则如果是异常是ThreadDeath(调用线程的stop方法抛出,已过时),忽略;否则打印日志。
6. 竞争条件:多个线程对共享数据操作的结果依赖于各线程访问的顺序
7. 锁(Lock),条件对象(条件变量), synchronized,volatile,常量:另写复习整理笔记整理,这里简单记录下
class Demo{
private Lock lock;
private Condition condition;
public Demon{
lock = new ReentrantLock();
condition = lock.newCondition();
}
public void demoMethod(){
lock.lock();
try{
while(notOkToProceed()){
condition.await();
}
businessLogic();
// condition.signal(); // 随机通知一个线程
condition.signalAll();
}
finally{
lock.unlock();
}
}
public boolean notOkToProceed(){...}
public void businessLogic(){...}
}
等价于
// !!每个对象有一个内部锁,并且该锁有一个内部条件
// !!静态方法声明为synchronized,获得相关类对象的内部锁
class Demo{
public Demon{
}
public synchronized void demoMethod(){
while(notOkToProceed()){
await()
}
businessLogic();
notifyAll();
}
public boolean notOkToProceed(){...}
public void businessLogic(){...}
}
客户端加锁:
(网上定义)对于使用某个对象X的客户端代码,使用X本身用于保护其状态的锁来保护这段客户端代码。
(自我理解)对于一个方法使用了某个可共享的对象,要想保证该方法的线性安全,也必须使用共享对象的锁,同时需要保证所有可修改方法都使用内部锁。
public class ListHelper<E>{
public List<E> list = Collections.synchronizedList(new ArrayList());
public synchronized boolean putIfAbsent(E x){ // <---- 非线性安全,因为使用的是ListHelper的内置锁
boolean absent = !list.contains(x);
if(absent){
list.add(x);
}
return absent;
}
}
应该修改为
public boolean putIfAbsent(E x){
synchronized(list){ // 修改为使用同一个锁
boolean absent = !list.contains(x);
if(absent){
list.add(x);
}
return absent;
}
}
volatile: 确保变量的更新操作通知到其他线程。(影响内存模型的可见性(直接从内存读取)、有序性(设置内存屏障,影响指令重拍),不影响原子性)
8. 线程局部变量 ThreadLocal
9. 阻塞队列(Blocking Queue):在队列满或者空时,插入或者取出操作会被阻塞
10. java.util.concurrent包下的线程安全集合
11. runnable, callable, future, completableFuture
12. 线程池以及Executor
方法 | 描述 |
newCachedThreadPool | 必要时创建线程,空闲线程保留60s |
newFixedThreadPool | 固定数量的线程 |
newSingleThreadExecutor | 一个线程 |
newScheduleThreadPool | 可替代Timer,用于定期执行 |
newSingleThreadScheduleExecutor |
13. Fork-join
14. 各种信号量
CyclicBarrier, Phaser, CountDonwLatch, Exchanger, Semaphore, SynchronousQueue