locks 接口
public interface Lock {void lock(); //获取锁void lockInterruptibly() throws InterruptedException; // 中断等待获取锁的线程boolean tryLock(); //尝试获取锁,如果成功返回true//尝试获取锁,在等待时间内,成功返回 true。支持打断boolean tryLock(long time, TimeUnit unit) throws InterruptedException;void unlock(); //释放锁Condition newCondition();}
reentrantlock
定义
reentrantLock 是独占锁,与synchronized 相同,并且也两者也同为 重入锁。
reentrantLock 可以相应 中断在获取锁时候。
reentrantLock 可以定义公平锁(默认为非公平),可以定义获取锁的等待时长。
专业术语的含义
重入锁: 当前线程获取 锁成功后,里面如果还需要获取这个锁,那么会立刻获取得到。
例子:
public class ReentrantLockTest {public static void main(String[] args) throws InterruptedException {ReentrantLock lock = new ReentrantLock();for (int i = 1; i <= 3; i++) {lock.lock();}for(int i=1;i<=3;i++){try {} finally {lock.unlock();}}}}
上面的代码通过lock()方法先获取锁三次,然后通过unlock()方法释放锁3次,程序可以正常退出。从上面的例子可以看出,ReentrantLock是可以重入的锁,当一个线程获取锁时,还可以接着重复获取多次。在加上ReentrantLock的的独占性,我们可以得出以下ReentrantLock和synchronized的相同点。
- 1.ReentrantLock和synchronized都是独占锁,只允许线程互斥的访问临界区。但是实现上两者不同:synchronized加锁解锁的过程是隐式的,用户不用手动操作,优点是操作简单,但显得不够灵活。一般并发场景使用synchronized的就够了;ReentrantLock需要手动加锁和解锁,且解锁的操作尽量要放在finally代码块中,保证线程正确释放锁。ReentrantLock操作较为复杂,但是因为可以手动控制加锁和解锁过程,在复杂的并发场景中能派上用场。
- 2.ReentrantLock和synchronized都是可重入的。synchronized因为可重入因此可以放在被递归执行的方法上,且不用担心线程最后能否正确释放锁;而ReentrantLock在重入时要却确保重复获取锁的次数必须和重复释放锁的次数一样,否则可能导致其他线程无法获得该锁。
公平锁与非公平锁:
公平锁是指当锁可用时,在锁上等待时间最长的线程将获得锁的使用权。而非公平锁则随机分配这种使用权。和synchronized一样,默认的ReentrantLock实现是非公平锁,因为相比公平锁,非公平锁性能更好。当然公平锁能防止饥饿,某些情况下也很有用。在创建ReentrantLock的时候通过传进参数true创建公平锁,如果传入的是false或没传参数则创建的是非公平锁
ReentrantLock lock = new ReentrantLock(true);
实现
浅层代码,之后的实现暂时不看。先了解特性吧。
/*** Creates an instance of {@code ReentrantLock} with the* given fairness policy.** @param fair {@code true} if this lock should use a fair ordering policy*/public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}
用法
package com.zxy.lock;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.ReentrantLock;/*** 公平锁与非公平锁** @author : wb-zxy450245* @date : 2020/6/17*/public class FairLockTest {//公平锁 or 非公平 new ReentrantLock(true|false);private static ReentrantLock reentrantLock = new ReentrantLock(false);public static void main(String[] args) {for (int i = 0; i < 5; i++) {new Thread(new LockDemo(i)).start();}}static class LockDemo implements Runnable {private int id = 0;public LockDemo(int id) {this.id = id;}@Overridepublic void run() {try {//为了说明问题,在每个线程获取锁前都睡 10毫秒。TimeUnit.MILLISECONDS.sleep(10L);} catch (InterruptedException e) {}for (int i = 0; i < 2; i++) {reentrantLock.lock();System.out.println("当前线程_" + id + "_for_" + i);reentrantLock.unlock();}}}}
参考地址:https://www.cnblogs.com/takumicx/p/9338983.html
公平锁是指当锁可用时,在锁上等待时间最长的线程将获得锁的使用权。而非公平锁则随机分配这种使用权。和synchronized一样,默认的ReentrantLock实现是非公平锁,因为相比公平锁,非公平锁性能更好。当然公平锁能防止饥饿,某些情况下也很有用。在创建ReentrantLock的时候通过传进参数true创建公平锁,如果传入的是false或没传参数则创建的是非公平锁、
//创建公平锁 - (默认参数是否false ,非公平锁)ReentrantLock lock = new ReentrantLock(true);
源码是:
/*** Creates an instance of {@code ReentrantLock} with the* given fairness policy.** @param fair {@code true} if this lock should use a fair ordering policy*/public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}
ReentrantLock可响应中断
参考:https://www.cnblogs.com/takumicx/p/9338983.html
3.2节
ReentrantReadWriteLock
ReentrantReadWriteLock可重入读写锁
使用参考地址:https://www.cnblogs.com/china2k/p/8013086.html
实现原理:https://www.toutiao.com/i6768421906807783949/?in_ogs=1&from=singlemessage&traffic_source=CS1114&utm_source=HW&source=search_tab&utm_medium=wap_search&prevent_activate=1&original_source=1&in_tfs=HW&channel=
读写锁:
AQS:https://www.yuque.com/haolonglong/msvmro/hspkh1
