AtomicInteger、AtomicLong、AtomicBoolean、AtomicReference
CAS机制只实现单个变量原子操作
Synchronized从偏向锁到轻量级锁再到重量级锁的过度。
compare and swap:比较并替换
CAS机制使用了3个基本操作数,内存值V,旧的预期值A,要修改的新值B
Synchronized属于悲观锁,CAS属于乐观锁
public final int incrementAndGet(){
for(;;){
int current = get();
int next = current + 1;
if(compareAndSet(currnet,next)){
return next;
}
}
}
private volatile int value;
public final int get(){
return value;
}
CAS缺点:
1.cpu开销较大
2.不能保证代码块的原子性
3.ABA问题:当一个值从A更新为B,又会更新为A。
解决方法:加版本号,引用这个类AtomicReference
CAS底层实现:调用了unsafe提供原子性操作方法(JNI)
2.volatile:轻量级的synchronized,高并发下保证变量的可见性。
可见性:在一个线程的工作内存中修改了该变量的值,该变量的值能立即回显到主内存中,从而保证所有线程看到这个变量的值是一致的。
非常受欢迎的单例模式写法
public class Singleton{
private static volatile Singleton instance;
private Singleton(){
}
public static Singleton getInstance(){
if(instance==null){
synchronized(Singleton.class){
if(instance==null){
instance = new Singleton();
}
}
}
return instance;
}
}
缺点:volatile不具备操作的原子性,他不适合在对该变量的写操作依赖于变量本身自己。可见性实现原理:happen-before原则
3.synchronized
synchronized叫同步锁,是Lock的一个简化版本。基于阻塞策略。
内部实现:重入锁ReentrantLock+一个Condition
4.ThreadLocal
提供线程内的局部变量。每个线程都自己管理自己的局部变量,互不影响。
使用ThreadLocal官方建议定义成 private static
注意:ThreadLocal在线程使用完毕后,要手动调用remove方法,移除他内部的值,防止内存泄露。
内部实现:ThreadLocal内部有一个静态类ThreadLocalMap,使用ThreadLocal的线程会与ThreadLocalMap绑定,维护这个Map对象。
缺点:内存泄露问题
对于ThreadLocal,一直涉及到内存泄露问题
当该线程不需要再操作某个ThreadLocal内的值时,应该手动的remove。
5.多线程锁