生产者消费者Java多线程实现
2013-12-31 17:41
441 查看
生产者和消费者问题是最经典的模拟多线程合作的问题之一,本文将提供一个具有多个生产者和多个消费者的Java实现。主要涉及到资源的锁定,多线程的合作,以及任务的抽象。
产品的抽象
每个产品都有一个唯一编号no,在构造函数里面初始化。static class Product { private static int index = 0; private int no; public Product() { index++; no = index; } }
工厂的抽象
此处我用工厂来存储产品,可能用SuperMarket定义会更合适。多个生产者和多个消费者都共享同一个工厂,所以工厂必须保证线程安全,需要锁定。此处选择使用java.util.concurrent.locks.Lock来加锁,还可以选择synchronized关键字或者BlockedQueue来实现。工厂的存储用LinkedList,删除频繁,效率比ArrayList高。当有产品的时候,还需要通知(signalAll)等待购买的消费者。此外,工厂还能够输出自己的仓库统计信息。
static class Factory { private LinkedList<Product> productList = new LinkedList<Product>(); private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public void addProduct(Product product) { lock.lock(); try { productList.offer(product); condition.signalAll(); } finally { lock.unlock(); } } public Product retrieveProduct() throws InterruptedException { lock.lock(); try { while (productList.isEmpty()) condition.await(); return productList.poll(); } finally { lock.unlock(); } } @Override public String toString() { lock.lock(); try { return "[Factory Info] " + productList.size() + " is stored."; } finally { lock.unlock(); } } }
生产者的抽象
每一个生产者也有一个唯一编号no,且与一个factory关联。值得说明的是Thread.interrupted()能够响应
Thread.currentThread().interrupt()。如果把sleep的时间改为随机数,应该更有意思。
static class Producer implements Runnable { private static int index = 0; private int no; private Factory factory; public Producer(Factory factory) { index++; no = index; this.factory = factory; } @Override public void run() { try { while (!Thread.interrupted()) { Product product = new Product(); factory.addProduct(product); print("Producer " + no + " create product " + product.no); TimeUnit.SECONDS.sleep(1); } } catch (InterruptedException ex) { print("Producer " + no + " is interrupted."); } } }
消费者的抽象
和生产者一样,每一个消费者也有一个唯一编号no,且与一个factory关联。如果factory库存中没有产品,消费者会忠诚的等待在那里。static class Consumer implements Runnable { private static int index = 0; private int no; private Factory factory; public Consumer(Factory factory) { index++; no = index; this.factory = factory; } @Override public void run() { try { while (!Thread.interrupted()) { Product product = factory.retrieveProduct(); print("Consumer " + no + " consume product " + product.no); TimeUnit.SECONDS.sleep(1); } } catch (InterruptedException ex) { print("Consumer " + no + " is interrupted."); } } }
模拟测试
用Executors以及ExecutorService来执行生产和消费任务,简化了代码逻辑。有意思的是调整生产者数量以及消费者数量,查看factory的库存,库存会不同,可见生产与市场之间的供需关系,一定要弄好,否则会很麻烦。public static void main(String[] args) { ExecutorService exe = Executors.newCachedThreadPool(); final Factory factory = new Factory(); for (int i = 0; i < 10; i++) { exe.execute(new Producer(factory)); } for (int i = 0; i < 6; i++) { exe.execute(new Consumer(factory)); } new Timer().schedule(new TimerTask() { @Override public void run() { print(factory); } }, 3000, 5000); }
相关文章推荐
- Java Note: 多线程的同步(互斥锁)的方法对比,信号量锁,读写锁的实现,生产者-消费者模式的实现
- Java多线程实现消费者/生产者模式
- Java多线程之生产者与消费者实现(1p1c)
- java 用多线程实现多生产者和多消费者模式
- Java多线程之~~~~使用wait和notify实现生产者消费者模型
- Java 多线程学习之生产者消费者模型:一个较完善的实现
- Java Note: 多线程的同步(互斥锁)的方法对比,信号量锁,读写锁的实现,生产者-消费者模式的实现
- 从Java多线程实现“生产者-消费者”模型来谈谈操作系统中线程状态的转换
- Java Note: 多线程的同步(互斥锁)的方法对比,信号量锁,读写锁的实现,生产者-消费者模式的实现
- Java——生产者消费者多线程实现
- Java多线程之~~~~使用wait和notify实现生产者消费者模型
- Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型
- Java Note: 多线程的同步(互斥锁)的方法对比,信号量锁,读写锁的实现,生产者-消费者模式的实现
- java多线程实现生产者/消费者同步
- 基于java多线程来实现生产者和消费者的实例
- Java多线程 多个生产者和多个消费者实现同步 jdk1.5
- Java Note: 多线程的同步(互斥锁)的方法对比,信号量锁,读写锁的实现,生产者-消费者模式的实现
- java多线程一 基本实现方法、消费者生产者队列、死锁
- Java 多线程实现生产者消费者问题(wait/notify)
- java 多线程实现生产者消费者模型