Java--JUC--生产者消费者(线程间的通信)
- 高内聚低耦合
- 高内聚:是指资源类中有各种的方法,复杂的操作实现,内聚所以的操作方法,但是只暴露出简单的接口供我们使用
- 低耦合:是指模块A和模块B之间的联系小,不是通过直接调用,可以是通过中间的接口,我们直接调用这和接口,这个接口会帮我具体调用B,实现了解耦
- 生产者消费者例子:题目:同一个资源类有++和--两个方法实现++和--交替执行10轮
- wait()和notifyAll()方法的父类是Object类
- 多线程判断要用while()不能用if(),防止虚假唤醒,好比说当wait()的线程被notifyAll()方法唤醒后必须再次进行判断条件,而if无法实现,所以我们使用while()作为判断
-
package com.model.concurrent; class AirCondition{ private int number=0; public synchronized void add() throws InterruptedException { // 1.判断 while (number!=0){ this.wait(); } // 2.干活 number++; System.out.println(Thread.currentThread().getName()+"\t"+number); // 3.通知 (唤醒其他的等待的线程) this.notifyAll(); } public synchronized void del() throws InterruptedException { // 1.判断 while (number==0){ this.wait(); } // 2.干活 number--; System.out.println(Thread.currentThread().getName()+"\t"+number); // 3.通知 (唤醒其他的等待的线程) this.notifyAll(); } } public class ProdConsumerDemo05 { /** * * 题目:同一个资源类有++和--两个方法 * 实现++和--交替执行10轮 * * 使用if判断时,为什么number的数量会超过1 * AB干活时++,CD干活是-- * 当A生产完一个蛋糕后, * B强到执行,进入到判断语句,执行等待,cpu去执行其他的线程 * A又强到执行,进入判断语句,执行等待,cpu去执行其他的线程 * c抢到执行,进入判断通过,执行--,唤醒等待的线程 * A,B等待时间长cpu优先执行AB,AB同时进行判断,同时通过进行++ * number的数量变成2 * * * */ public static void main(String[] args) { AirCondition airCondition=new AirCondition(); new Thread(() ->{ for (int i = 0; i < 10; i++) { try { airCondition.add(); } catch (InterruptedException e) { e.printStackTrace(); } } },"A").start(); new Thread(() ->{ for (int i = 0; i < 10; i++) { try { airCondition.add(); } catch (InterruptedException e) { e.printStackTrace(); } } },"B").start(); new Thread(() ->{ for (int i = 0; i < 10; i++) { try { airCondition.del(); } catch (InterruptedException e) { e.printStackTrace(); } } },"C").start(); new Thread(() ->{ for (int i = 0; i < 10; i++) { try { airCondition.del(); } catch (InterruptedException e) { e.printStackTrace(); } } },"D").start(); } }
-
使用lock方式实现的代码
-
lock和synchonized:
-
lock : condition.awati();condition.signal();
-
synchronized: this.wait() ; this.notify()
-
-
package com.model.concurrent; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ProdConsumerDemo06 { public static void main(String[] args) { Aircondition aircondition=new Aircondition(); new Thread(() ->{ for (int i = 0; i < 10; i++) { aircondition.add(); } },"A").start(); new Thread(() ->{ for (int i = 0; i < 10; i++) { aircondition.add(); } },"B").start(); new Thread(() ->{ for (int i = 0; i < 10; i++) { aircondition.del(); } },"C").start(); new Thread(() ->{ for (int i = 0; i < 10; i++) { aircondition.del(); } },"C").start(); } } class Aircondition{ private int num=0; private Lock lock=new ReentrantLock(); //可重复的递归的非公平锁 private Condition condition=lock.newCondition(); public void add(){ lock.lock(); try { while(num!=0){ condition.await(); // this.wait(); } num++; System.out.println(Thread.currentThread().getName()+"\t"+num); condition.signalAll(); // this.notifyAll(); }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } public void del(){ lock.lock(); try { while(num==0){ // this.wait(); condition.await(); } num--; System.out.println(Thread.currentThread().getName()+"\t"+num); // this.notifyAll(); condition.signalAll(); }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } }
-
- 小总结:
-
高聚低合前提下,线程操作资源类
-
判断/干活/通知
-
防止虚假唤醒
-
-