线程是个很重要的东西,今天的博客更新用线程实现经典的生产者,消费者模式。
主类里面的常数
// 计数器,用于生产线程退出 private static int pCount = 0; // 计数器,用于消费退出 private static int cCount = 0; // 线程锁 private static Object key = new Object(); // 资源库最大值 private static final int MAX_SIZE = 100; // 生产者,消费者共同拥有的资源 private static List<Object> list = new ArrayList<Object>(MAX_SIZE);
main函数
public static void main(String[] a) { // 生产者,消费者线程池 // ExecutorService poolProducer = Executors.newFixedThreadPool(10); ExecutorService poolConsumer = Executors.newFixedThreadPool(10); producer p = new ThreadTest3().new producer(1); producer p2 = new ThreadTest3().new producer(2); producer p3 = new ThreadTest3().new producer(3); consumer c1 = new ThreadTest3().new consumer(1); consumer c2 = new ThreadTest3().new consumer(2); consumer c3 = new ThreadTest3().new consumer(3); c1.setPriority(10); p.setPriority(1); p3.setPriority(1); p2.setPriority(1); poolConsumer.submit(c1); poolConsumer.submit(c2); poolConsumer.submit(c3); poolConsumer.submit(p); poolConsumer.submit(p2); poolConsumer.submit(p3); System.out.println("-----"); poolConsumer.shutdown(); System.out.println("-----"); }
生产者线程:
class producer extends Thread { private int i; public producer(int i) { this.i = i; } public void run() { while (true) { synchronized (key) { try { if (list.size() == MAX_SIZE) { System.out.println("生产者" + i + "获取权限,但是资源库中资源已满,等待消费者消费;"); Thread.sleep(1000); key.wait(); } else { list.add(new Object()); System.out .println("生产者" + i + "获取权限,向资源库放资源;资源库中现有资源个数为:" + list.size()); Thread.sleep(1000); key.notify(); } } catch (Exception e) { System.out.println("error---------------------"); } } } } }
消费者线程
class consumer extends Thread { private int i; public consumer(int i) { this.i = i; } public void run() { while (true) { synchronized (key) { if (list.size() == 0) { System.out.println("消费者" + i + "获取权限,但是资源库中没有资源,等待生产;"); try { Thread.sleep(1000); key.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block System.out.println("error---------------------"); } } else { System.out.println("消费者" + i + "获取权限,现在资源库有资源;" + list.size() + "个,消费1个资源"); list.remove(list.size() - 1); try { Thread.sleep(1000); key.notify(); } catch (InterruptedException e) { // TODO Auto-generated catch block System.out.println("error---------------------"); } } } } } }
执行结果:
消费者1获取权限,但是资源库中没有资源,等待生产; ----- ----- 生产者3获取权限,向资源库放资源;资源库中现有资源个数为:1 生产者2获取权限,向资源库放资源;资源库中现有资源个数为:2 生产者2获取权限,向资源库放资源;资源库中现有资源个数为:3 生产者1获取权限,向资源库放资源;资源库中现有资源个数为:4 消费者3获取权限,现在资源库有资源;4个,消费1个资源 消费者2获取权限,现在资源库有资源;3个,消费1个资源 消费者2获取权限,现在资源库有资源;2个,消费1个资源 消费者3获取权限,现在资源库有资源;1个,消费1个资源 消费者3获取权限,但是资源库中没有资源,等待生产; 生产者1获取权限,向资源库放资源;资源库中现有资源个数为:1 生产者2获取权限,向资源库放资源;资源库中现有资源个数为:2 生产者2获取权限,向资源库放资源;资源库中现有资源个数为:3 生产者2获取权限,向资源库放资源;资源库中现有资源个数为:4 生产者2获取权限,向资源库放资源;资源库中现有资源个数为:5 生产者3获取权限,向资源库放资源;资源库中现有资源个数为:6 生产者3获取权限,向资源库放资源;资源库中现有资源个数为:7 生产者3获取权限,向资源库放资源;资源库中现有资源个数为:8
结果分析:
从结果里面可以看到,几个生产者和消费者线程是杂乱无章得执行的,生产者生产数据,消费者消费数据,同一时间只有有一个生产者或一个消费者处理数据。
尽管在主函数中三个生产者以setPriority的方式改变了权限,但是貌似在执行过程中没有体现出来。所以平时编程的时候,最好不要期待setPriority方法能有什么出色的表现。
结果里面的两行----- 说明主函数poolConsumer.shutdown();执行了,线程池执行了shutdown语句,但是还在执行的线程不会因为线程池的关闭而马上退出执行。
附上源码文件,网上备份。