package com.charles.algorithm; import java.util.LinkedList; public class ProducerConsumer { /** * @Desc: multiple sub-classes */ static final int MAX_SIZE = 10; LinkedList<Integer> list = new LinkedList<Integer>(); public static void main(String[] args) { ProducerConsumer pc = new ProducerConsumer(); Consumer consumer = pc.new Consumer(); Producer producer = pc.new Producer(); // define 4 producers for (int i = 0; i < MAX_SIZE / 3 + 1; i++) { new Thread(producer).start(); } // define 3 consumers for (int i = 0; i < MAX_SIZE / 3; i++) { new Thread(consumer).start(); } } class Producer implements Runnable { @Override public void run() { while (true) { produce(); } } private void produce() { synchronized (list) { while (MAX_SIZE <= list.size()) { try { System.out.println("Producer-" + Thread.currentThread().getName() + " Waiting..."); list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } sleep(); list.add(list.size() + 1); list.notifyAll(); System.out.println("Producer-" + Thread.currentThread().getName() + " produce:" + list.size() + " left: " + list.size()); } } } class Consumer implements Runnable { @Override public void run() { while (true) { consume(); } } private void consume() { synchronized (list) { while (0 >= list.size()) { try { System.out.println("Consumer-" + Thread.currentThread().getName() + " Waiting..."); list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } sleep(); int num = list.pollLast(); System.out.println("Consumer-" + Thread.currentThread().getName() + " consume: " + num + " left: " + list.size()); list.notifyAll(); } } } private void sleep() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }