locks 接口

  1. public interface Lock {
  2. void lock(); //获取锁
  3. void lockInterruptibly() throws InterruptedException; // 中断等待获取锁的线程
  4. boolean tryLock(); //尝试获取锁,如果成功返回true
  5. //尝试获取锁,在等待时间内,成功返回 true。支持打断
  6. boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
  7. void unlock(); //释放锁
  8. Condition newCondition();
  9. }

**

reentrantlock

定义
reentrantLock 是独占锁,与synchronized 相同,并且也两者也同为 重入锁。
reentrantLock 可以相应 中断在获取锁时候。
reentrantLock 可以定义公平锁(默认为非公平),可以定义获取锁的等待时长。

专业术语的含义
重入锁: 当前线程获取 锁成功后,里面如果还需要获取这个锁,那么会立刻获取得到。
例子:

  1. public class ReentrantLockTest {
  2. public static void main(String[] args) throws InterruptedException {
  3. ReentrantLock lock = new ReentrantLock();
  4. for (int i = 1; i <= 3; i++) {
  5. lock.lock();
  6. }
  7. for(int i=1;i<=3;i++){
  8. try {
  9. } finally {
  10. lock.unlock();
  11. }
  12. }
  13. }
  14. }

上面的代码通过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或没传参数则创建的是非公平锁

  1. ReentrantLock lock = new ReentrantLock(true);

实现
浅层代码,之后的实现暂时不看。先了解特性吧。

  1. /**
  2. * Creates an instance of {@code ReentrantLock} with the
  3. * given fairness policy.
  4. *
  5. * @param fair {@code true} if this lock should use a fair ordering policy
  6. */
  7. public ReentrantLock(boolean fair) {
  8. sync = fair ? new FairSync() : new NonfairSync();
  9. }

用法

  1. package com.zxy.lock;
  2. import java.util.concurrent.TimeUnit;
  3. import java.util.concurrent.locks.ReentrantLock;
  4. /**
  5. * 公平锁与非公平锁
  6. *
  7. * @author : wb-zxy450245
  8. * @date : 2020/6/17
  9. */
  10. public class FairLockTest {
  11. //公平锁 or 非公平 new ReentrantLock(true|false);
  12. private static ReentrantLock reentrantLock = new ReentrantLock(false);
  13. public static void main(String[] args) {
  14. for (int i = 0; i < 5; i++) {
  15. new Thread(new LockDemo(i)).start();
  16. }
  17. }
  18. static class LockDemo implements Runnable {
  19. private int id = 0;
  20. public LockDemo(int id) {
  21. this.id = id;
  22. }
  23. @Override
  24. public void run() {
  25. try {
  26. //为了说明问题,在每个线程获取锁前都睡 10毫秒。
  27. TimeUnit.MILLISECONDS.sleep(10L);
  28. } catch (InterruptedException e) {
  29. }
  30. for (int i = 0; i < 2; i++) {
  31. reentrantLock.lock();
  32. System.out.println("当前线程_" + id + "_for_" + i);
  33. reentrantLock.unlock();
  34. }
  35. }
  36. }
  37. }

参考地址:https://www.cnblogs.com/takumicx/p/9338983.html
公平锁是指当锁可用时,在锁上等待时间最长的线程将获得锁的使用权。而非公平锁则随机分配这种使用权。和synchronized一样,默认的ReentrantLock实现是非公平锁,因为相比公平锁,非公平锁性能更好。当然公平锁能防止饥饿,某些情况下也很有用。在创建ReentrantLock的时候通过传进参数true创建公平锁,如果传入的是false或没传参数则创建的是非公平锁、

  1. //创建公平锁 - (默认参数是否false ,非公平锁)
  2. ReentrantLock lock = new ReentrantLock(true);

源码是:

  1. /**
  2. * Creates an instance of {@code ReentrantLock} with the
  3. * given fairness policy.
  4. *
  5. * @param fair {@code true} if this lock should use a fair ordering policy
  6. */
  7. public ReentrantLock(boolean fair) {
  8. sync = fair ? new FairSync() : new NonfairSync();
  9. }

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

面试题: