线程
一个程序里面的不同的执行路径。
- Thread的run和start的区别
run只是单纯的掉用重写的run方法,但是start方法会以多线程的方式进行启动,即会单独启动一个线程进行调用run方法
创建线程
- 继承Thread
- 实现Runnable接口(调用的时候需要将new对象传到一个Thread类的对象中)
- 线程池Executor.newCachedThread
简单方法
- sleep
- yield返回到就绪状态,短暂让出
- join。t1调用t2的join方法,等待t2运行结束
锁升级:偏向锁-》自旋锁
当前线程访问不会进行加锁,当下一次线程进行访问的时候,判断是否是当前锁进访问,如果不是,则进行加锁,同时升级为自旋锁,线程数变多以后升级为重量级锁
lock锁是一个CAS操作
Synchronized是一个wait队列
当操作时间长则进行重量级锁
volatile
- 保证线程可见性(多个线程访问会有个副本,当前线程的修改只是对当前线程修改,其余线程并不会即时改变)
CPU的缓存一致性协议 - 禁止指令重排序 (i++)
double check lock(单例模式双重检查锁)
instance = new Magr();
申请内存–>初始化–>赋值给instance
指令重排序会导致第三步到第二步调换,导致线程获取到没有进行初始化的对象(依然单例但是没有获取到初始化数据
CAS(无锁优化 自旋 乐观)
- compare and set
- 进行改变的时候进行比较 如果值没有进行改变则认为没有其他线程进行访问改变
- ABA问题处理可以加版本号
- 底层实现 unsafe类 1.8想要使用只能进行反射,11版本进行改动成为单例模式,可以调用get方法进行使用。