多线程并发安全
1. 多线程并发安全问题 多线程环境下,多个线程是并发执行的,并且基于无序的cpu的争夺机制,线程的执行顺序是不确定的,
此时如果多个线程同时去操作共享资源,就有可能因为线程的无序执行,产生一些意外的情况,这种问题就统称为多线程并发安全问题。
2. 多线程并发安全问题产生的条件
a. 有共享资源
b. 有多线程并发操作了共享资源
c. 有多线程并发操作了共享资源 且涉及到了修改操作
3. 解决多线程并发安全问题
解决多线程并发安全问题的关键,就是破坏产生多线程并发安全问题的条件
禁止共享资源 -- ThreadLocal
禁止多线程并发操作 -- Synchronized
禁止修改 -- ReadWriteLock
4. Synchronized同步代码块使用
原理:
通过控制并发线程无法同时操作共享资源,从而实现线程安全问题的解决。
细节:
在存在多线程并发安全问题的场景下,可以使用synchronized代码块,将产生多线程并发安全问题的代码包裹起来,并选择一个锁对象。
锁对象可以任意的选择,但是要保证,多个并发的线程操作的都是同一个锁对象。
锁对象并没有实际的作用,唯一的作用是在锁对象身上会标记一个锁的状态 - [关锁状态] [开锁状态]
在线程执行到同步代码块时,会在当前锁对上上检查,如果是锁是[开锁状态],则进入同步代码块,同时将锁状态改为[关锁状态]
此时再有其他线程试图获取该对象上的锁时,锁已经是[关锁状态],无法获得到锁,线程只能在锁下等待,进入阻塞状态。
直到之前得到锁的线程将synchronized代码块执行完,释放锁,重新将锁变为 [开锁状态],等待的线程,才可以从阻塞状态中恢复,重新参与锁的争夺。
因此,同一时刻,只能有一个并发线程执行可能造成线程安全问题的代码,破坏了多线程并发的状态,从而解决多线程并发安全问题
同步代码块的结构:
单独声明同步代码块:
synchronized(锁对象){
要同步的代码
}
在方法上声明同步,则称之为同步方法:
Public synchronized void mx(){
…
}
同步方法中的锁对象,普通方法是this,静态方法时当前类的字节码
锁对象的选择的原则:
任意对象都可以作为锁对象使用
但要保证,所有的并发线程都应该能够访问到该所对象,且访问的必须是同一个锁对象
常用的锁对象:
自己创建一个专用的对象
使用共享资源作为锁对象
使用类的字节码对象作为锁对象
————————————————
版权声明:本文为CSDN博主「Gavin_W_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Gavin_W_/article/details/82776746

浙公网安备 33010602011771号