4.线程通信问题(重点)

java多线程文章目录

目录

生产者消费者问题

问题解决

实现代码

原理

Condition

三种方法


生产者消费者问题

生产者消费者问题,也称有限缓冲问题,是一个线程同步问题的经典案例。

  • 在缓冲区(仓库)为空时,消费者不能进行消费
  • 在缓冲区(仓库)为满时,生产者不能进行生产
  • 在一个线程进行生产或者消费时,其他线程不能进行消费或者生产操作,即保持线程间的同步

问题解决

        因为需要保持线程间的同步,即一个线程消费(或生产)完,其它线程才能争抢CPU资源:生产者线程在生产之前,需要等待直至获取自己所需的信号量之后(即仓库为空),才会进行生产的操作;同样,对于消费者线程,在消费之前需要等待直到没有线程在访问共享区(缓冲区),再进行消费的操作,之后再解锁并唤醒其他可用阻塞线程。

实现代码

篇幅有限,便在网上找了篇文章。主要是因为懒 ¬o( ̄- ̄メ)

Java代码解决生产者---消费者问题(两种方法)_阿顾同学的博客-CSDN博客_用java语言实现生产者消费者问题https://blog.csdn.net/u010452388/article/details/82624599

原理

在Java对象中有两种池:

锁池---------->sychronized

等待池-------->wait(),notify(),notifyAll()

  1. 如果一个线程调用了某个对象的wait()方法,那么该线程进入到该对象的等待池中(并且已经将锁释放)
  2. 如果未来某一时刻,另外一个线程调用了相同对象的notify()方法或者notifyAll()方法,那么该等待池中的线程就会被唤醒,然后进入到对象的锁池里面去获得该对象的锁
  3. 如果获得锁成功后,那么该线程就会沿着wait()方法之后的路径继续执行。注意是沿着wait()方法之后

wait()方法和notify()方法,是必须放在同步方法或者同步代码块中才有效的.因为在同步的基础上进行线程的通信才是最有效的

线程生命完整周期图

Condition

Oralce官方文档:Condition (Java Platform SE 8 )

Condition是在Java 1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、notify(),使用Condition1的await()、signal()这种方式实现线程间协作更加安全和高效。

  • 它的更强大的地方在于:能够更加精细的控制多线程的休眠与唤醒。对于同一个锁,我们可以创建多个Condition,在不同的情况下使用不同的Condition
  • 一个Condition包含一个等待队列。一个Lock可以产生多个Condition,所以可以有多个等待队列
  • 在Object的监视器模型上,一个对象拥有一个同步队列和等待队列,而Lock(同步器)拥有一个同步队列和多个等待队列
  • Object中的wait(),notify(),notifyAll()方法是和"同步锁"(synchronized关键字)捆绑使用的;而Condition是需要与"互斥锁"/"共享锁"捆绑使用的
  • 调用Condition的await()、signal()、signalAll()方法,都必须在lock保护之内,就是说必须在lock.lock()和lock.unlock之间才可以使用
    • Conditon中的await()对应Object的wait();
    • Condition中的signal()对应Object的notify();
    • Condition中的signalAll()对应Object的notifyAll()

三种方法

void await() throws InterruptedException { }

造成当前线程在接到信号或被中断之前一直处于等待状态

与此 Condition 相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下四种情况之一之前,当前线程将一直处于休眠状态:

  • 其他某个线程调用此 Condition 的 signal() 方法,并且碰巧将当前线程选为被唤醒的线程
  • 其他某个线程调用此 Condition 的 signalAll() 方法
  • 其他某个线程中断当前线程,且支持中断线程的挂起
  • 发生“虚假唤醒

在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证它保持此锁

void signal() {}

唤醒一个等待线程

如果所有的线程都在等待此条件,则选择其中的一个唤醒。在从 await 返回之前,该线程必须重新获取锁

void signalAll() {}

唤醒所有等待线程

如果所有的线程都在等待此条件,则唤醒所有线程。在从 await 返回之前,每个线程都必须重新获取锁

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值