java 多线程开发注意事项
多线程开发的三大特性
-
有序性 可见性 对修改后的数据可以看到拥有可见性 原子性 代码在执行的时候必须一次执行完,一次成功或者是一次失败,一次线程对一段代码有掌控,就像事务里面的原子一样
线程,本地内存你,驻村交互图
在jvm中的三大特性
有序性 编译器会对代码以及指令进行编译重排. 1. 编译器优化重排 2. 指令集重排 3. 内存系统重排 经过三次重新排序经生成最终的指令集. 在单线程的执行过程中,编译器的重排不会导致结果发生变化.
可见性 jvm在执行多线程的时候会将驻村中的变量拿到线程中的内存中,如果在线程不安全的情况下,A线程在对变量进行更改的时候B线程并不知道,B线程会执行自己的更改,在这种情况下就是操作不可见.
原子性 一个操作是不可终端的,及时在多线程的环境下,一个操作开始就不会被其他线程影响. 下图中只有语句一是原子性操作
通过加锁的形式来保证线程安全
正常情况下两个线程是交替的执行,如果我们加锁两个线程在执行的时候就是串行的.
JMM定义内存访问规范
通过JMM定义内存访问规范,实现有序性可见性,原子性.
-
程序顺序原则 锁规则 volatile变量规则 传递性规则,A先发生于B,B先发生于C那么A必然先于C 线程启动规则 会先调用线程启动中的内容 线程的终止 线程中断规则 对象中介规则
通过满足上面的条件来避免加锁
线程安全的基本概念
什么是线程安全? 当过多个线程访问某个类是,不管运行时环境采用何种类,调度方式或者这些线程将如何交替执行,并且在主要调用代码中不需要任何额外的同步活协同,这个类都能表现出正确的行为,那么这个类就是线程安全的. 通过加锁而实现的线程安全不能叫做线程安全.
同步机制
-
监视器所(synchronized) 显示锁(ReentrantLock,ReadWriteLock) 原子变量(atomicInteger,atomicLong,AtomicBollean) Volatile 在使用的时候一定要注意使用原子操作
note 经过jvm的优化在1.5版本之后synchronized性能已经高于显示锁了 - 增加了自旋锁等优化模式
问题:遇到同步问题如何选择具体的实现方式 舞曲:Synchronized是解决一切并发问题的最佳选择
共享的和可变的变量
保证共享使用的变量在一个线程中就可以保证线程安全.
线程封闭技术
当访问共享的可变数据时,通常需要同步.一种避免同步的方式就是不共享数据.如果仅在单线程内访问数据,就不需要同步,这种技术成为线程封闭.
将属性设置为不可变变量
当对象满足一下条件是才是不可变的: 对象创建后不可修改 对象所有的与都是final 最佳方案:使用线程安全对象是实现线程安全的最佳方法.java.util.concurrent
上一篇:
IDEA上Java项目控制台中文乱码