多线程并发的安全问题
当多个线程并发操作同一个临界资源时,由于线程切换的时机不确定,导致操作顺序发生混乱情况,严重时可能导致系统瘫痪。
解决方法有一下几种:同步锁,同步块,互斥锁等。
1、同步锁(synchronized)加到被多个线程使用的方法上
当一个方法使用关键字synchronized修饰后,
* 这个方法称为:同步方法
* 同步方法要求多个线程不能同时进入到方法内部
* 必须“排队”运行(同步运行)
在方法上使用synchronized也是有同步监视器对象的,而该对象就是方法所属对象“this”
缺点是:效率不高,时间变长了
2、同步块
- 语法
- synchronized(同步监视器对象,(this)){
- 需要同步运行的代码片段}
- 有效的缩小同步范围可以保证并发安全的前提下提高并发的效率,使用
- 同步块可以更准确的锁定需要同步运行的代码片段
使用同步块时要求指定同步监视对象,即上锁对象
* 该对象可以是java中任何类型的实例,只要保证对个线程看到的该对象
* 是“同一个”即可
* 否则没有同步效果
synchronized(new object)就不行,因为new object 所对应的实例对象不一样,,所以
锁的对象不一样,没有同步效果
3、互斥锁
- 1,当使用synchronized锁定多个代码片段,2,并且指定的同步监视器对象是
- 同一个时,这些代码片段就是互斥的,多个线程不能同时执行这些代码
- 片段。但如果只锁了一个片段和一个没锁的,那么这两个线程可以同时
执行
注:
静态方法若使用synchroined,那么一定具有同步效果
- 静态方法默认指定的同步监视器对象为该类的类对象
- 类对象反面反射知识点会介绍
Thread.yield();//主动让出cpu时间,模拟线程没时间发生切换