启动线程的3种方法
1、集成Thread类
2、实现Runnable类
3、线程池
线程状态
1.新建一个线程是新建状态:NEW
2.调用.start()方法后进入Runable状态
3.Runable状态包括2个小状态:Ready和Running
4.使用sleep,wait方法进入TimeWaiting或Waiting状态
5.TimeWaiting或Waiting状态结束范文Runable
6.锁可以让线程进入Blocked状态
7.线程结束Teminated
synchronized
synchronized是锁一个对象
fin
锁升级
偏向锁 --> 自旋锁 --> 重量级锁
偏向锁
markword 记录这个线程ID (偏向锁)
自旋锁
如果线程争用:升级为 自旋锁:(while循环等着)
重量级锁
打转儿的次数够多(JDK1.6规定为10次),或者打转儿的人够多(JDK目前规定为自旋线程超过CPU内核数的一半)
升级为重量级锁 - OS
策略
执行时间短(加锁代码),线程数少,用自旋
执行时间长,线程数多,用系统锁,用synchronized
优化
采用细粒度的锁,可以使线程争用时间变短,从而提高效率 —锁的细化
- 锁定某对象o,如果o的属性发生改变,不影响锁的使用
- 但是如果o变成另外一个对象,则锁定的对象发生改变
- 应该避免将锁定对象的引用变成另外的对象
- final Object o = new Object(); --推荐使用final
原子性
synchronized锁机制保证一组操作一定是全部完成才会提交也就是原子性
有序性
JMM中关于synchronized有如下规定,线程加锁时,必须清空工作内存中共享变量的值,从而使用共享变量时需要从主内存重新读取;线程在解锁时,需要把工作内存中最新的共享变量的值写入到主存,以此来保证共享变量的可见性