线程不安全

参考:https://www.cnblogs.com/dhcao/p/10982278.html

线程不安全

​ 多线程为什么不安全?现在应该有答案了!究其根本,是因为线程之间无法准确的知道互相之间的状态。那么如何使得多线程安全呢,从内存角度来讲,保证线程的工作内存之间的可见性和有序性,是多线程并发安全的基础。例如volatile关键字和synchronized关键字,我们除了从作用上了解他们,还可以从更深层的内存语义上理解,他们之所以能够一定程度的解决线程安全问题,是因为他们约束了一定的内存处理方式!

volatile关键字已经实现了线程间数据同步,又要synchronized干什么呢?呵呵,它们之间有两点不同。首 先,synchronized获得并释放监视器——如果两个线程使用了同一个对象锁,监视器能强制保证代码块同时只被一个线程所执行——这是众所周知的事 实。但是,synchronized也同步内存:事实上,synchronized在“主”内存区域同步整个线程的内存。
 

java线程的3个特性:

2.2.1、 指令重排序

​ 定义:

​ 计算机为了性能优化会对汇编指令进行重新排序,以便充分利用硬件的处理性能。

2.2.2、 有序性

​ 定义:

​ 在Java中,单线程总是顺序执行的!

​ 当编译器和处理器重排序时,必须保证,不管怎么重排序,单线程的执行结果不能被改变

2.2.3、 可见性

​ 定义:

​ 多线程中,若线程A中进行的每一步都可以被线程B观测到,则称线程A对线程B具有可见性。

​ 线程B不仅可以看到线程A处理的结果,还能准确的知道在处理过程中,每一个状态的改变,已经状态改变的顺序;

​ Java线程的通讯是透明的,线程之间不可以直接进行信息交换,所有的通讯必须同内存共享!所以多线程是天然不可见的,就是说如果不主动干涉的话,线程之间不可见,为什么呢,因为线程虽然第一步处理步骤a,第二步处理步骤b,但是先将步骤b的结果写入主内存,后将步骤a的结果写入主内存,则对观测线程来说,首先看到的是步骤b的结果,然后才是步骤a的结果!

 

线程不安全

​ 多线程为什么不安全?现在应该有答案了!究其根本,是因为线程之间无法准确的知道互相之间的状态。那么如何使得多线程安全呢,从内存角度来讲,保证线程的工作内存之间的可见性和有序性,是多线程并发安全的基础。例如volatile关键字和synchronized关键字,我们除了从作用上了解他们,还可以从更深层的内存语义上理解,他们之所以能够一定程度的解决线程安全问题,是因为他们约束了一定的内存处理方式!

volatile关键字已经实现了线程间数据同步,又要synchronized干什么呢?呵呵,它们之间有两点不同。首 先,synchronized获得并释放监视器——如果两个线程使用了同一个对象锁,监视器能强制保证代码块同时只被一个线程所执行——这是众所周知的事 实。但是,synchronized也同步内存:事实上,synchronized在“主”内存区域同步整个线程的内存。

即:volatile只是在线程内存和“主”内存间同步某个变量的值,而synchronized通过锁定和解锁某个监视器同步所有变量的值。显然 synchronized要比volatile消耗更多资源