谈谈对Java线程通信方式的理解

Java面试 潘老师 8个月前 (09-04) 163 ℃ (0) 扫码查看

Java面试题:谈谈对Java线程通信方式的理解?

得分点:

Monitor、Condition

标准回答:

在Java中,常用的线程通信方式有两种:基于Monitor(监视器)的线程通信和基于Condition的线程通信。线程通信通常需要建立在线程同步的基础上,因此选择通信方式取决于线程同步的方式。

Monitor(基于synchronized的线程通信)

如果采用synchronized关键字进行同步,线程通信通常依赖于Monitor,也称为同步监视器。在synchronized同步模式下,锁对象可以是任意类型,因此通信方法通常定义在Object类中,包括:

  • wait(): 当线程调用wait()时,它会释放锁并进入等待状态。
  • notify(): 当其他线程调用notify()时,会唤醒等待在此锁上的一个线程。
  • notifyAll(): 当其他线程调用notifyAll()时,会唤醒等待在此锁上的所有线程。

Condition(基于Lock和Condition的线程通信)

JDK 1.5引入了Lock接口及其实现类,提供了更灵活的同步方式。如果采用Lock对象进行同步,线程通信通常依赖于ConditionCondition对象是由Lock对象创建的,它依赖于特定的Lock对象。Condition对象中的通信方法类似于Object类中的方法,包括:

  • await(): 当通过Condition调用await()时,当前线程会释放锁并进入等待状态。
  • signal(): 当通过Condition调用signal()时,会唤醒等待在此Condition上的一个线程。
  • signalAll(): 当通过Condition调用signalAll()时,会唤醒等待在此Condition上的所有线程。

加分回答:

线程同步是基于同步队列实现的,而线程通信是基于等待队列实现的。调用等待方法时,当前线程将被添加到等待队列。调用通知方法时,等待队列中的一个或多个线程将被移动到同步队列。

因为synchronized通常只有一个Monitor,因此它只有一个等待队列。相比之下,Lock对象可以创建多个Condition,因此它可以拥有多个等待队列。多个等待队列提供了更大的灵活性,因此基于Condition的通信方式更为推荐。

举例来说,在实现生产者-消费者模型时,生产者需要通知消费者,消费者需要通知生产者。避免出现生产者通知生产者或消费者通知消费者的情况非常重要。如果使用synchronized实现此模型,由于只有一个等待队列,生产者和消费者都将加入同一个队列,可能会导致误通知的问题。而使用Lock时,可以创建两个Condition,一个用于生产者,一个用于消费者,以有效地区分它们,避免误通知。这种灵活性使基于Condition的通信更加可控。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/javainterview/8628.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】