Java JDK1.8(22) - 多線程併發設計模式 - 生產者-消費者設計模式多種寫法

生產者-消費者設計模式

/**

 * 生產者-消費者模式:是一個非常經典的多線程模式,在實際開發中應用非常廣泛的思想理念,在生產-消費模式中,

 * 通常有兩類線程,即N個生產線程和N個消費者線程。

 * 生產者負責提交用戶請求,消費者線程則負責具體處理生產者提交的任務,在生產者和消費者之間通過共享內存緩存區進行通信。

 * 典型的應用:MQ

 */

public class C05ProducerConsumer {

    public static void main(String[] args) throws InterruptedException {

         //任務

         LinkedBlockingDeque<Task2> taskQueue = new LinkedBlockingDeque<Task2>(10);

        

         //生產者

         Producer producer1 = new Producer(taskQueue);

         Producer producer2 = new Producer(taskQueue);

         Producer producer3 = new Producer(taskQueue);

        

         //消費者

         Consumer consumer1 = new Consumer(taskQueue);

         Consumer consumer2 = new Consumer(taskQueue);

         Consumer consumer3 = new Consumer(taskQueue);

        

         //線程池運行

         ExecutorService pool = Executors.newCachedThreadPool();

         pool.execute(producer1);

         pool.execute(producer2);

         pool.execute(producer3);

         pool.execute(consumer1);

         pool.execute(consumer2);

         pool.execute(consumer3);

        

         Thread.sleep(13000);

         producer1.stop();

         producer2.stop();

         producer3.stop();

         Thread.sleep(12000);

        

    }

}

/**

 * 生產者

 */

class Producer implements Runnable {

   

    //任務

    private BlockingQueue<Task2> taskQueue;

   

    //用於停止運行,強制從主內存刷新

    private volatile boolean isRun = true;

 

    //id生成

    private static AtomicInteger id = new AtomicInteger();

   

    public Producer(BlockingQueue<Task2> taskQueue) {

         super();

         this.taskQueue = taskQueue;

    }

 

    /*

     * 不眠不休的生產任務

     */

    @Override

    public void run() {

         while (isRun) {

             Task2 task2 = new Task2(this.id.getAndIncrement(), Thread.currentThread().getName());

             try {

                  //模擬數據產生過程

                  Thread.sleep(2000);

                  //2秒進不去隊列就失敗

                  boolean offer = this.taskQueue.offer(task2, 2, TimeUnit.SECONDS);

                  System.out.println("生產 - " + task2.getId());

                  if (!offer) {

                      System.out.println(id + " - 任務提交失敗");

                  }

             } catch (InterruptedException e) {

                  e.printStackTrace();

             }

         }

    }

   

    /**

     * 停止運行

     */

    public void stop() {

         isRun = false;

    }

   

}

/**

 * 消費者

 */

class Consumer implements Runnable {

    //任務

    private BlockingQueue<Task2> taskQueue;

   

    public Consumer(BlockingQueue<Task2> taskQueue) {

         super();

         this.taskQueue = taskQueue;

    }

 

    /*

     * 消費者消費

     */

    @Override

    public void run() {

         while (true) {

             try {

                  Task2 take = this.taskQueue.take();

                  //模擬數據消費過程

                  Thread.sleep(2000);

                  System.out.println("消費:" + Thread.currentThread().getName() + " - " + take.getId());

             } catch (Exception e) {

                  e.printStackTrace();

             }       

         }

    }

}

class Task2 {

    private Integer id;

   

    private String desc;

 

    public Task2(Integer id, String desc) {

         super();

         this.id = id;

         this.desc = desc;

    }

 

    public Integer getId() {

         return id;

    }

 

    public void setId(Integer id) {

         this.id = id;

    }

 

    public String getDesc() {

         return desc;

    }

 

    public void setDesc(String desc) {

         this.desc = desc;

    }

}

/**

 * 案例一:生產者-消費者

 * 採用JDK1.5Lock的方式

 */

public class J16MessagePCByLock {

    public static void main(String[] args) {

         ProductA productA = new ProductA();

         ProducerA producer = new ProducerA(productA);

         ConsumerA consumer = new ConsumerA(productA);

         new Thread(producer,"p1").start();

         new Thread(producer,"p2").start();

         new Thread(consumer,"c1").start();

         new Thread(consumer,"c2").start();

    }

}

/**

 * 商品

 */

class ProductA {

   

    /**

     * 是否有商品

     */

    boolean isHashProduct = false;

   

    /**

     * 自定義鎖

     */

    Lock lock = new ReentrantLock();

   

    /**

     * 監視器

     */

    Condition condition = lock.newCondition();

   

    /**

     * 生產

     */

    public void product() throws InterruptedException {

         //生產,上鎖

         lock.lock();

        

         while (isHashProduct) {

             //已有商品,進入等待,放棄CPU執行權、放棄鎖

             condition.await();

         }

        

         isHashProduct = true;

         Thread.sleep(3000);

         System.out.println("生產一臺筆記本");

 

         //喚醒消費者

         condition.signalAll();

         //生產完成,釋放鎖

         lock.unlock();

    }

    /**

     * 消費者

     */

    public void consumer() throws InterruptedException {

         //消費上鎖

         lock.lock();

        

         while (!isHashProduct) {

             //沒有商品,進入等待

             condition.await();

         }

        

         isHashProduct = false;

         Thread.sleep(3000);

         System.out.println("消費一臺筆記本");

        

         //喚醒生產者

         condition.signalAll();

         lock.unlock();

    }

}

class ProducerA implements Runnable {

   

    /**

     * 生產者

     */

    ProductA productA;

   

    public ProducerA(ProductA productA) {

         super();

         this.productA = productA;

    }

 

    @Override

    public void run() {

         try {

             productA.product();

         } catch (InterruptedException e) {

             e.printStackTrace();

         }

    }

}

class ConsumerA implements Runnable {

   

    /**

     * 生產者

     */

    ProductA productA;

   

    public ConsumerA(ProductA productA) {

         super();

         this.productA = productA;

    }

 

    @Override

    public void run() {

         try {

             productA.consumer();

         } catch (InterruptedException e) {

             e.printStackTrace();

         }

    }

}

/**

 * 案例二:生產者-消費者

 * 採用JDK1.5Lock的方式:多個監視器

 */

public class J17MessagePCByLockMC {

    public static void main(String[] args) {

         ProductB productB = new ProductB();

         ProducerB producer = new ProducerB(productB);

         ConsumerB consumer = new ConsumerB(productB);

         new Thread(producer,"p1").start();

         new Thread(producer,"p2").start();

         new Thread(consumer,"c1").start();

         new Thread(consumer,"c2").start();

    }

}

/**

 * 商品

 */

class ProductB {

   

    /**

     * 是否有商品

     */

    boolean isHashProduct = false;

   

    /**

     * 自定義鎖

     */

    Lock lock = new ReentrantLock();

   

    /**

     * 監視器

     */

    Condition pCondition = lock.newCondition();

    Condition cCondition = lock.newCondition();

   

    /**

     * 生產

     */

    public void product() throws InterruptedException {

         //生產,上鎖

         lock.lock();

        

         while (isHashProduct) {

             //已有商品,進入等待,放棄CPU執行權、放棄鎖

             pCondition.await();

         }

        

         isHashProduct = true;

         Thread.sleep(3000);

         System.out.println("生產一臺筆記本");

 

         //喚醒消費者

         cCondition.signal();

         //生產完成,釋放鎖

         lock.unlock();

    }

    /**

     * 消費者

     */

    public void consumer() throws InterruptedException {

         //消費上鎖

         lock.lock();

        

         while (!isHashProduct) {

             //沒有商品,進入等待

             cCondition.await();

         }

        

         isHashProduct = false;

         Thread.sleep(3000);

         System.out.println("消費一臺筆記本");

        

         //喚醒生產者

         pCondition.signal();

         lock.unlock();

    }

}

class ProducerB implements Runnable {

   

    /**

     * 生產者

     */

    ProductB productB;

   

    public ProducerB(ProductB productB) {

         super();

         this.productB = productB;

    }

 

    @Override

    public void run() {

         try {

             productB.product();

         } catch (InterruptedException e) {

             e.printStackTrace();

         }

    }

}

class ConsumerB implements Runnable {

   

    /**

     * 生產者

     */

    ProductB productB;

   

    public ConsumerB(ProductB productB) {

         super();

         this.productB = productB;

    }

 

    @Override

    public void run() {

         try {

             productB.consumer();

         } catch (InterruptedException e) {

             e.printStackTrace();

         }

    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章