java 的线程安全
方法/步骤
1
1.不可变。只要一个不可变的对象被创建出来,其外部可见状态永远不会改变,永远不会在多个线程之间看到不同的状态。不可变带来的安全性是最简单纯粹的。在java语言中如果共享数据是一个基本数据类型。只要在定义的时候使用final即可。
2
如果是一个对象:例如String,它调用subString,replace等方法,对它本身没有影响,生成一个新的字符串。
3
使用Synchronization实现线程安全,jdk1.5之前的版本多线程的情况下吞吐量下降的特别块。可以使用ReentrantLock,但是在jdk1.6之后性能基本差不多。所以推荐jdk1.6之后使用Synchronization。在未来的性能改造中也会更加偏向原生的synchronization。
方法/步骤2
1
long与double是线程不安全的,必须在synchronized中操作,或是声明为volatile。每个线程执行时将会把局部变量放在各自栈帧的工作内存中,线程间不共享,故不存在线程安全问题。
2
将变量声明为volatile。使用volatile,是告诉JVM和编译器,该变量每次被线程访问时,都强迫从共享内存中重新读取出。这种方式,线程安全。
3
volatile关键字,会在最终编译出来的指令上加上lock前缀,lock前缀的指令做三件事情 (1)、防止指令重排序(这里对本问题的分析不重要,后面会详细来讲)
4
(2)、锁住总线或者使用锁定缓存来保证执行的原子性,早期的处理可能用锁定总线的方式,这样其他处理器没办法通过总线访问内存,开销比较大,现在的处理器都是用锁定缓存的方式,在配合缓存一致性来解决。 (3)、把缓冲区的所有数据都写回主内存,并保证其他处理器缓存的该变量失效