多线程(15)线程通信2
一:其实线程通信也是线程同步的一种
一:生产者消费者初级模型
|
|
|
|
总结: 这里是应该是哇哈哈哈冰红茶,但是这里是康师傅冰红茶; 这里需要我们将共享资源product作为同步监视器,分别在生产者与消费者都上锁,synchronized(product)就可以了,我们的锁对象是产品; 这样我们就不会出现康师傅冰红茶的情况了; (生成这在生产的时候,消费者就没有办法进行消费)
同步监视器:synchronized(obj) 中obj称为同步监视器
同步代码块中同步监视器可以是任何对象,但是推荐使用共享资源资源作为同步监视器;
同步方法中无需指定同步监视器,因为同步方法的同步监视器是this,也就是该对象本身
同步监视器的执行过程:
第一个线程访问,锁定同步监视器。执行其中代码
第二个线程访问,发现同步监视器被锁定,无法访问
第一个线程访问完毕,解锁同步监视器
第二个线程访问,发现同步监视器未锁,锁定并访问
二:上面列子,我们仓库只能放一个,但是会遇到生产者不短生产,消费者不断的消费问题
真正线程同步:java提供了3个方法解决线程之间的通信问题(为啥把这三个方法放在了Object中,因为我们锁的对象的最上级肯定是object)
wait():表示线程一直等待,直到其它线程通知
wait(long timeout):线程等待指定毫秒参数的时间
wait(long timeout,int nanos):线程等待指定毫秒,微妙的时间
notify():唤醒一个处于等待状态的线程(除了自己本身以外的线程)
notifyAll();唤醒同一个对象上所有调用wait()方法的线程,优先级别高的线程优先运行(除了自己本身以外的其他线程)
均是java.long.Object类的方法,都只能在同步方法或者同步代码块中使用,否则会抛出异常
三:需要使用同步
生产者和消费者是俩个线程,他们共享同一个产品,因此,生产者和消费者都需要进行同步,而且必须使用同一个(同步监视器),否则会出现线程安全问题。
四:需要进行线程通信
只进行同步,并不能解决生产者和消费者交替执行的功能,此时,需要使用线程通信来实现该功能。
在产品中添加一个是否有商品的标识,然后我们在生产中判断如果有商品我们就进行等待, 如果没有商品的话,我们进行生产,然后设置为有商品,并且唤醒我们的消费线程, 消费线程在进行判断是否有商品,如果没有的话进行等待,如果有的话,我们进行消费,消费完毕后,设置无商品,然后激活生产者,进行生产。
|
|
|
|
如果我们上边不加锁的话比如product.wait()或者product.notify()不加product的话,默认的是this.wait(), 所以是当前对象的等待与激活,会出现就问题;
|