Java 日常开发中用到的锁
名称 |
概述 |
悲观锁 |
每次拿数据的时候都会上锁,别的线程去拿数据的时候就会阻塞,比如synchronized |
乐观锁 |
每次去拿数据的时候都认为其他线程不会修改,更新的时候判断是否被更新数据,如果被修改就拒绝更新 |
公平锁 |
指多个线程按照申请锁的顺序来获取锁,能保证每个线程都能拿到锁,比如ReentrantLock |
非公平锁 |
获取锁的方式是随机获取的,保证不了每个线程都能拿到锁,比如synchronized、ReentrantLock |
可重入锁 |
也叫递归锁,在外层使用锁之后,在内层仍然可以使用,并且不会发生死锁 |
不可重入锁 |
若当前线程执行某个方法已经获取该锁,在方法中尝试再次获取锁时,就会获取不到而被阻塞 |
自旋锁 |
线程在获取锁的时候,如果锁已经被其它线程获取,该线程将循环等待,不断的判断锁是否能被成功获取 |
synchronized:
1. 是悲观锁会引起其它线程阻塞,Java内置关键字
2. 无法判断是否获取锁的状态,独占锁,锁可重入,不可中断,只能是非公平
3. 加锁解锁的过程是隐式的,用户不用手动操作,优点是操作简单但显得不够灵活
4. 一般并发场景足够,可以放在被递归执行的方法上,且不用担心线程最后能否正确释放锁
ReentrantLock:
1. 是Lock接口的实现类,悲观锁
2. 可以判断是否获取到锁,独占锁,可重入,可判断、可公平/非公平
3. 需要手动加锁和解锁,且解锁的操作尽量要放在finally代码块中,保证线程正确释放锁
4. 创建的时候通过传进参数true创建公平锁,默认非公平锁,传入false也是非公平锁
5. 底层是AQS的state和FIFO队列来控制加锁