CAS
- CAS(Compare And Swap),处理器会比较当前内存地址上的值 和 线程中变量的值(预期值)是否相等,如果相等则替换内存地址上的值为新值,如果不相等则不更新,硬件层面上支持使用一条指令来实现上面的操作,x86中是
cmpxchgl指令 - CAS操作不涉及线程上下文切换,并且不使用锁,会提高系统的并发性
ABA问题:一个线程将变量A改为了变量B,之后又改为了变量A,另一个线程在执行CAS操作时会认为该变量没有发生变化,可能会导致错误。解决方案:添加版本号进行对比,可以使用AtomicStampedReference类
Synchorized
synchorized修饰实例方法时,锁对象是当前的实例对象;synchorized修饰静态方法时,锁对象是当前的class类对象;synchorized作用于代码块时,锁对象是括号里面的对象synchorized是可重入锁,一个线程可以重复获取到该锁,每获取一次锁,计数器加一,释放锁时,计数器减一,直到计数器为0,锁才会真正释放
锁升级过程:
- 在没有锁竞争的情况下,一个线程来加锁,JVM会向锁对象的对象头中写入该线程id (这时候的锁叫
偏向锁),后续该线程再进入该锁时,无需进行额外的同步操作 - 在锁轻度竞争的时候,会升级为
轻量级锁,JVM会在当前线程中创建一个栈帧,通过CAS操作将这个栈帧的地址写入对象头中,如果成功表示该线程获取到了锁,如果失败则表示其他线程已经持有该锁,此时会升级为重量级锁 - 当锁竞争激烈时,JVM会升级为重量级锁,
synchorized修改代码块时,线程会尝试获取monitor对象的所有权,抢到了就是成功获取到锁,抢不到线程就会阻塞,等待重新获取锁
Synchorized和ReentrantLock
synchorized和ReentrantLock都是可重入锁synchorized是非公平锁,不支持条件判断,不支持设置超时时间,不需要手动释放锁ReentrantLock既可以是非公平锁也可以是公平锁(默认是非公平锁),允许设置获取锁的超时时间
ThreadLocal
-
基本使用
public class UserContext { private static ThreadLocal<User> CONTEXT = new ThreadLocal<User>(); public static User getUser() { return CONTEXT.get(); } public static void setUser(User user) { CONTEXT.set(user); } public static void remove() { CONTEXT.remove(); } } -
每个线程内部维护了一个
ThreadLocalMap对象,ThreadLocalMap以ThreadLocal为key,线程变量副本为value -
ThreadLocalMap中的key是弱引用,java中所使用的线程往往是线程池中的线程,一般不会被销毁,对ThreadLocal的引用就会一直存在,导致内存释放不掉
Volatile
volatile可以保证可见性,当一个线程修改了volatile变量的值后,新值会立即被刷新到主内存中,其他线程在读取该变量时可以立即获取到最新的值,避免由于缓存一致性问题导致 ”看见“旧值的现象volatile底层会加一个lock前缀指令进行总线锁定,总线监听到修改了共享数据后,会让其他处理器中的缓存更新或失效volatile可以禁止 jvm 指令重排,保证在多线程环境下也能正常运行。正常情况:1. 为对象分配内存,2. 初始化,3. 将对象引用指向对应内存地址。指令重排可能变成1 3 2,这样可能会发生问题
其他内容
死锁:两个线程都想获取对方已经拥有的锁,避免死锁的方法:
- 避免在一个锁的代码块中再次尝试获取另一个锁
- 使用尝试获取锁的方法,比如
ReentrantLock的trylock方法,Semaphore的tryAcquire方法,如果获取不到使用其他方案 - 减小锁的控制范围
线程安全的方式
- 同步锁:
synchorized、ReentrantLock - 原子操作类:
AtomicInteger、AtomicReference - 线程安全的容器:
ConcurrentHashMap等,避免手动加锁 - 使用局部变量
原子性、可见性、有序性
- 原子性:一组操作要么全部执行成功,要么全部不执行
- 可见性:一个线程修改共享变量的值后,其他线程能够立即看到这个修改后的值
- 有序性:程序的执行顺序和代码的先后顺序一致,但是多线程环境下,编译器会对指令进行重排序,进而出现并发问题
相关文章
- CAS:note.youdao.com/s/AJECfbdA
- ThreadLocal:note.youdao.com/s/7pvkie8N
- CPU缓存架构:note.youdao.com/s/ALicPbhV
- JUC并发工具类:note.youdao.com/s/dbBcYl4a