线程
使用方法
实现Runnable接口
实现Callable接口
- 可以用Future获得返回值
继承Thread类
Java提供的机制
线程池
- Future submit
- void execute
Daemon(守护线程)
- JVM在所有非守护线程结束时退出
- 栗子:负责GC的线程
sleep
- 休眠当前正在执行的线程
- 异常不能跨线程传播,所以必须在本地处理异常
yield
- 告知线程调度者可以切换到其他线程了,但线程调度者未必听从
setPriority
- 优先级高的线程被操作系统调度的优先级较高,但不能确保优先级高的线程一定先被执行
状态
特指 Java 虚拟机的线程状态
new
- 创建后尚未启动
Runnable
- 在JVM层面可运行,具体有没有运行要看底层操作系统的资源调度
blocked
- 因为请求锁而不能得陷入阻塞
waiting
blocked是被动的,waiting是主动的
进入
- wait(无时间参数)
- join(无时间参数)
- park
退出
- notify/notifyAll
- 目标线程执行完毕
- unpark
timed_waiting
在一定时间后被唤醒
进入
- wait(有时间参数)
- join(有时间参数)
- parkNanos/parkUtil
terminated
- 线程任务执行完毕或异常
中断
线程
interrupt
- 可以立即停止一个正在阻塞、等待的线程
InterruptedException
- 如果线程正处于阻塞、等待的状态,interrupt会使线程发生interruptedException
interrupted
- interrupt会标记目标线程,使线程的interrupted返回true
线程池
shutdown
- 所有线程执行完后关闭
shutdownNow
- 对每个线程调用interrupt方法
互斥同步
方法
synchronized
- 同步代码块
- 同步方法
- 同步一个类
- 同步一个静态方法
ReentrantLock
- lock
- unlock
- tryLock(long timeout,TimeUnit unit)
比较
实现者
- synchronized由jvm实现
- ReentrantLock由jdk实现
性能
- 新版本性能相似
等待锁的线程是否可中断
- synchronized:否
- ReentrantLock:是
公平锁
- synchronized:只能非公平锁
- ReentrantLock:默认非公平锁
死锁
- 使用synchronized,jvm确保不会死锁
选择
- 优先synchronized
多线程协作
join
- 将当前线程挂起直到目标线程结束
synchronized
wait
将当前线程挂起等待notify或notifyAll
wait VS sleep
- wait会释放锁,而sleep不会
notify
- 唤醒一个因为请求锁而阻塞的线程
notifyAll
ReentrantLock
await
- 将当前线程挂起等待signal或signalAll
signal
signalAll
Java内存模型
作用
- 屏蔽各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下都能达到一致的内存访问效果
内存
分类
- 主内存
- 工作内存
内存间交互
特点
原子性
- 内存间的交互操作具有原子性
- 使用原子类(AtomicInteger)确保操作的原子性
- 使用synchronized确保操作的原子性
可见性
- volatile
- synchronized
- final
重排
- 编译器和处理器的指令重排可能会影响并发的正确性
- volatile
- synchronized
先行发生原则
single thread rule
- 单线程内严格串行
monitor lock rule
- unlock先于lock
volatile variable rule
- 对volatile变量的写操作先于读操作
线程安全
不可变
- final
- String
- 枚举类型
- Collections.unmodifiableXXX()
互斥(阻塞)同步
- synchronized
- ReentrantLock
非阻塞同步
乐观锁
StampedLock
- tryOptimisticRead
- validate
无同步
栈封闭
- 并发访问方法局部变量不会有线程安全问题
线程本地存储
可重入代码(pure code)