使用线程的目的
1、并行处理,加快程序运行速度
java中如何应用线程
1、实现Runnable接口
2、Thread
3、Callable/Future带返回值的线程
4、ThreadPool 线程池
实际应用
1、线程池,不会直接new Thread()
线程中断
1、thread.interrupteed();
线程的几种状态:
1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
3.阻塞(BLOCKED):表示线程阻塞于锁。
4.等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
5.超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
6. 终止(TERMINATED):表示该线程已经执行完毕
线程运行状态图:
synchronized 范围:
java1.6引入了轻量级锁,在之前synchronized都是重量级锁,只要线程没有获取到锁就会阻塞。
synchronized升级过程:无锁> { 偏向锁(cas乐观锁) > 轻量级锁(自旋锁) } > 重量级锁(mutex)
synchronized是非公平锁
public class SynDome {
// 对象级别锁,与method2等价
//同一SynDome实例对象,A、B两个线程同时访问需要等待
//不同SynDome实例对象,A、B两个线程同时访问无需等待
public synchronized void method(){
}
// 对象级别锁,与method1等价,但锁粒度更细
//同一SynDome实例对象,A、B两个线程同时访问需要等待
//不同SynDome实例对象,A、B两个线程同时访问无需等待
public void method2(){
synchronized(this){
}
}
// 类级别锁
//同一SynDome实例对象,A、B两个线程同时访问需要等待
//不同SynDome实例对象,A、B两个线程同时访问需要等待
public void method3(){
synchronized(SynDome.class){
}
}
}
A、B两个线程同时获取一个对象的锁是会用cas(compare and swap)原子操作。
线程标记对象的对象头:
偏向锁获得及撤销:
偏向锁
1、CAS比较对象头中的线程id实现原子性
2、乐观锁
3、compare and swap(value,expect,update)
4、有限次数自旋尝试CAS,超过次数锁膨胀成重量级锁被阻塞并加入同步队列中
5、自适应自旋次数或通过jvm参数设置自旋次数 preBlockSpin
轻量级锁获得及膨胀:
线程通信机制
wait()/notify()/notifyAll()
wait()第一个获取锁的线程会阻塞同时释放锁,并加入等待队列
notify()唤醒等待队列里其中一个线程加入到同步队列中去争抢锁
notifyAll()唤醒等待队列里所有的线程加入到同步队列中去争抢锁
wait会释放锁资源,并且释放CPU资源;
sleep会释放CPU资源,不会释放锁资源。
重量级锁ObjectMonitor
使用monitorenter争抢锁,成功后获得对象头,退出使用monitorexit解锁
线程的阻塞和唤醒存在从内核态到用户态的切换,性能上带来开销!!
线程安全性
1、volatile保证可见性
2、如何保证可见性,Lock指令
3、可见性到底是什么,硬件层面、jmm层面
CPU层面提供了指令 -> 内存屏障
内存屏障用来解决可见性问题
CPU层面提供了三种屏障:写屏障(store barrier)、读屏障(load barrier)、全屏障(full barrier)
volatile -> lock(缓存锁)-> 内存屏障-> 可见性
JMM内存模型
可见性问题的本根原因:高度缓存、重排序
JMM最核心的价值是解决了有序性、可见性
JMM语言及别抽象内存模型
volatile、synchronized、final、happens-before
源代码 -> 编译器的重排序-> cpu层面的重排序(指令级、内存)-> 最终执行的指令
happens-before规则
那些操作会建立happens-before规则
1、程序顺序规则
2、volatile规则
3、传递性规则
4、start规则
5、join规则
6、synchronized规则
volatile不解决原子性,解决了可见性,通过禁止指令重排序实现
atomic 通过 cas 实现原子性
synchronized解决了可见性、原子性、有序性