并发工具类-Lock

85 阅读2分钟

Lock&Condition

Lock

为什么要增加Lock

Java已经在语言层面实现了synchronized,为什么还要再造一个轮子工具Lock呢?
因为sychronized无法实现破坏抢占条件,它获取不到即进入阻塞

锁的设计方案

设计一把互斥锁,去解决上面问题的方案有哪些?

  1. 支持响应终端
    void lockInterruptibly() throw InterruptedException
  2. 支持超时
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException
  3. 非阻塞地获取锁
    boolean tryLock()

如何保证可见性

简单解释:利用volatile相关的Happen-Before规则
锁的实现:内部只有一个volatile的成员变量state

可重入

  1. 可重复锁:线程可以重复获取同一把锁
  2. 可重入函数:多个线程可以同时调用该函数,每个线程都可以获取正确的执行结果。这可以保证这个函数是线程的

公平锁与非公平锁

  1. 公平锁:唤醒等待线程时,谁的等待时间长就唤醒谁
  2. 非公平锁:唤醒等待线程时,随机唤醒一个等待的线程

锁的自家实践

  1. 永远只在更新对象的成员变量时加锁
  2. 永远只在访问可变的成员变量时加锁
  3. 永远不在调用其他对象的方法时加锁
因为无法保证其他对象的方式是否线程安全

Condition

为什么要增加Condition

synchronized只支持一个条件变量

线程等待和通知

与synchonized里面的wait()、notify()、notifyAll()想对应的是 await()、signal()、signalAll()

同步和异步

不需要等待返回结果,Java默认执行是同步的
Java实现异步的方法:前者是调用方实现,后者是调用方法实现

  1. 异步调用:【调用方】创建一个子线程,在子线程中执行方法调用,这种方式呗称为异步调用
  2. 异步方法:在方法实现的时候,内部创建一个线程去执行主要逻辑,主线程里面直接return

异步转同步(Dubbo源码分析)

调用方 --> 获取结果 --> 等待返回 --> 返回之后唤醒【调用方】