多线程-线程安全
- 线程安全的概念:如果说多线程下运行的结果是我们预期的,即与单线程下的运行结果是一致的,那我们就说这个线程是安全的。
- 线程不安全的原因
(1)原子性被破坏
什么是原子性?原子性就是当A在一个房间内干自己的事情的时候,因为该房间没有上锁,所以此时B也可以进入该房间,这样一来使得A的隐私被侵犯,导致相应的运行结果也会出错。这就是不具备原子性。
如何解决?我们可以给房间上一把锁,当A执行的时候,其他任何进程都不会打扰到它,这样就保证了原子性。
(2)没有遵循可见性
为了提高效率,JVM在工作时会将数据放在工作内存中执行,但这样一来就有问题,共享的变量在多线程之间不能被及时看到,这就是可见性的问题。
(3)代码的顺序性引起的
什么是顺序性?JVM在执行时,会将一部分代码自动排序,从而使得运行效率更高,但有时候这样会让运行结果出错,屁如下面5条指令:
如果按照我们预期的排序:1234,运行结果是31
但如果JVM排序为:1243,运行结果将变为30
这样一来导致运行结果出现了问题,这就是代码的顺序性。 - 使用synchronized关键字-监视器锁解决线程不安全
synchronized底层是使用操作系统的mutex lock实现的。
(1)当线程释放锁的时候,JMM会将工作内存中的共享变量释放到主内存中。
(2)当线程获取锁时,JMM会把该线程对应的本地内存置为无效。从而使得被监视器保护的临界区代码必须从主内存中读取共享变量。
synchronized用的锁是存在Java对象头里的,synchronized同步快对同一条线程来说是可重入的,不会出现自己把自己锁死的问题;同步块在已进入的线程执行完之前,会阻塞后面其他线程的进入。
4.sync