并发基础
Java内存模型
- lock
- unlock
- read
- load
- use
- assign
- write
并发的测试工具 - postman:HTTP请求,非专业的并发测试工具
- Apache Bench:无图形化界面
常用命令:
ab -n 1000 -c 50 http://url
表示1000个请求 50个并发 - JMeter 专业的测试工具
线程安全性
- 原子性
Atomic包保证了原子性
主要是通过CAS操作保证线程安全,CAS即是 compareAndSwap 是native方法,底层方法非Java实现的
AtomicLong/LongAdder
AtomicLong使用Atomic的CAS操作是在死循环内不断尝试,直到满足条件再进行操作
LongAdder:高并发时提高了性能
AtomicReference/AtomicReferenceFieldUpdater
用于更新一个勒种的某个变量
该变量需要vilotile修饰
AtomicStampReference 用于解决CAS操作的ABA问题
锁保证了原子性
synchronized 依赖JVM
synchronized:子类不会继承这个属性
对于代码块和方法:不同对象之间是互不影响的
对于静态方法和静态类:在同一时间只有一个对象获得锁
synchronized lock Atomic的区别
synchronized 不可终端,适合竞争不激烈的环境,可读性好
lock:可终端,多样化同步,竞争激烈
Atomic:竞争激烈,比Lock性能好,但是只能同步一个值 - 可见性
线程间共享变量不可见的原因
1.线程交叉执行
2.重排序结合线程交叉
3.共享变量更新后未在工作内存与主内存之间及时更新
synchronized
1.解锁前,必须将共享变量最新值刷到主内存
2.加锁时,清空工作内存共享变量的值,并从主内存读取(加锁和解锁是统一把锁)
volatile
1.volatile不能保证原子性
2.volatile通过加入内存屏障和禁止重排序优化实现可见性
可用于以下情况
1.对于写操作不依赖当前值
2.该变量不包含在其他式子中
一般作为状态标识量
- 有序性
- volatile,synchronized,lock都能保证有序性
happen-before原则
1.程序的次序
2.锁定 unlock在lock前
3.volatile写操作优于读
4.传递
5.线程启动
6.线程中断
7.线程终结
8.对象终结
若无法从happen-before推导出,则可以进行重排序
发布对象
使一个对象能够被当前范围之外的代码使用
对象逸出
错误的发布,当一个对象还没构造完成,就使它能被其他线程看见
单例模式
1.饿汉 --》线程安全的
2.懒汉–》线程不安全的
3.枚举–》线程安全的并且推荐
双重同步锁的懒汉模式也是线程不安全的,原因是指令重排,volatile可以发挥作用
不可变对象final
类 不能被修饰
方法:1.锁定方法不能被继承类修改
2.效率
变量 基本类型是不能修改的
引用类型是不能指向其他对象