《Java并发编程实战》课程学习笔记(八)

文章详细介绍了JavaSDK中的Lock和Condition接口在并发编程中的作用,以及ReentrantLock的公平锁与非公平锁策略。此外,还探讨了如何通过Lock和Condition实现多条件变量的管程,并讲解了Dubbo如何通过DefaultFuture实现异步转同步的RPC调用。
摘要由CSDN通过智能技术生成

Lock 和 Condition

隐藏在并发包中的管程

  • Java SDK 并发包通过 Lock 和 Condition 两个接口来实现管程,其中 Lock 用于解决互斥问题,Condition 用于解决同步问题。

如何保证可见性

  • Java SDK 里面 Lock 的使用,有一个经典的范例,就是 try{}finally{},需要重点关注的是在 finally 里面释放锁。
  • Java SDK 里面 Lock 靠什么保证可见性呢?
    • Java SDK 里面锁利用了 volatile 相关的 Happens-Before 规则。
    • Java SDK 里面的 ReentrantLock,内部持有一个 volatile 的成员变量 state,获取锁的时候,会读写 state 的值;解锁的时候,也会读写 state 的值。

什么是可重入锁

  • 所谓可重入锁,顾名思义,指的是线程可以重复获取同一把锁。

公平锁与非公平锁

  • 在使用 ReentrantLock 的时候,你会发现 ReentrantLock 这个类有两个构造函数,一个是无参构造函数,一个是传入 fair 参数的构造函数。
  • fair 参数代表的是锁的公平策略,如果传入 true 就表示需要构造一个公平锁,反之则表示要构造一个非公平锁。
  • 锁都对应着一个等待队列,如果一个线程没有获得锁,就会进入等待队列,当有线程释放锁的时候,就需要从等待队列中唤醒一个等待的线程。
    • 如果是公平锁,唤醒的策略就是谁等待的时间长,就唤醒谁,很公平;
    • 如果是非公平锁,则不提供这个公平保证,有可能等待时间短的线程反而先被唤醒。

锁的最佳实践

  • 永远只在更新对象的成员变量时加锁
  • 永远只在访问可变的成员变量时加锁
  • 永远不在调用其他对象的方法时加锁

Dubbo 如何用管程实现异步转同步?

  • Condition 实现了管程模型里面的条件变量。
  • Java 语言内置的管程里只有一个条件变量,而Lock&Condition 实现的管程是支持多个条件变量的。
  • 那如何利用两个条件变量快速实现阻塞队列呢?
    • 一个阻塞队列,需要两个条件变量,一个是队列不空(空队列不允许出队),另一个是队列不满(队列已满不允许入队)。
      • Lock 和 Condition 实现的管程,线程等待和通知需要调用 await()、signal()、signalAll(),它们的语义和 wait()、notify()、notifyAll() 是相同的。
      • Lock&Condition 实现的管程里只能使用 await()、signal()、signalAll(),而 wait()、notify()、notifyAll() 只有在 synchronized 实现的管程里才能使用。

同步与异步

  • 同步和异步的区别到底是什么呢?
    • 通俗点来讲就是调用方是否需要等待结果,如果需要等待结果,就是同步;
    • 如果不需要等待结果,就是异步。
  • 同步,是 Java 代码默认的处理方式。如果你想让你的程序支持异步,可以通过下面两种方式来实现:
    • 调用方创建一个子线程,在子线程中执行方法调用,这种调用我们称为异步调用;
    • 方法实现的时候,创建一个新的线程执行主要逻辑,主线程直接 return,这种方法我们一般称为异步方法。

Dubbo 异步转同步

  • 我们工作中经常用到的 RPC 调用,在 TCP 协议层面,发送完 RPC 请求后,线程是不会等待 RPC 的响应结果的。
  • 知名的 RPC 框架 Dubbo 给我们做了异步转同步的事情,那它是怎么做的呢?
    • Dubbo 异步转同步的功能是通过 DefaultFuture 这个类实现的。
    • 当 RPC 返回结果之前,阻塞调用线程,让调用线程等待;当 RPC 返回结果后,唤醒调用线程,让调用线程重新执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值