Java多线程之生产者消费者问题<二>:使用重入锁、条件变量优雅地解决生产者消费者问题

来源:互联网 发布:塔利班和中国关系 知乎 编辑:程序博客网 时间:2024/04/29 01:47

        Java5中新增了大量线程同步的功能,比如显式Lock,读写锁ReadWriteLock,条件变量Condition等,虽然这些功能使用之前的synchronized同步关键字都可能实现,但自己使用同步关键字不仅管理混乱,而且容易出错。 如下是使用显式Lock和条件变量Condition更好的解决生产者消费者问题,关于lock和condition读者可以自己查阅相关说明,也很好理解。

Consumer.java

package CreatorAndConsumer;public class Consumer implements Runnable {    /**     * 线程资源     */    private Plate plate;    public Consumer(Plate plate) {        this.plate = plate;    }    @Override    public void run() {        plate.getEgg();    }}
Creator.java

package CreatorAndConsumer;/** * 生产者 * * @author Martin */public class Creator implements Runnable {    /**     * 线程资源     */    private Plate plate;    public Creator(Plate plate) {        this.plate = plate;    }    @Override    public void run() {        Object egg = new Object();        plate.addEgg(egg);    }}

Plate.java

package CreatorAndConsumer;import java.util.List;import java.util.concurrent.locks.*;/** * 盘子,表示共享的资源 * * @author Martin */public class Plate {    private List<Object> eggs = new ArrayList<Object>();    /**     * 锁     */    private Lock lock;    /**     * 大于0条件变量,用于保证消费时有资源可消费     */    private Condition more0Condition;    public Plate() {        lock = new ReentrantLock();        more0Condition = lock.newCondition();    }    /**     * 获取蛋     *     * @return     */    public Object getEgg() {        lock.lock();        try {            while (eggs.size() < 1) {                more0Condition.await();            }            System.out.println("消费者取蛋,当前剩余:" + eggs.size());            Object egg = eggs.get(0);            eggs.remove(0);            return egg;        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            lock.unlock();        }        return null;    }    /**     * 加入蛋     *     * @return     */    public void addEgg(Object egg) {        lock.lock();        System.out.println("生产者生蛋,当前剩余:" + eggs.size());        eggs.add(egg);        more0Condition.signalAll();        lock.unlock();    }}

Tester.java
package CreatorAndConsumer;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Tester {    public static void main(String[] args)    {        //共享资源        Plate plate = new Plate();        ExecutorService pool = Executors.newFixedThreadPool(100);        //添加生产者和消费者        for(int i = 0 ; i < 1000; i ++)        {            pool.execute(new Creator(plate));            pool.execute(new Consumer(plate));        }        pool.shutdown();    }}
</pre><pre>

0 0