生产者/消费者问题的多种实现方式

1.使用阻塞队列实现
我们知道Thread 的子类和 实现runnable 接口的最主要的区别在于通过同一个Runnable 接口实现类 创建的线程可以共享变量,下面的例子中,生产者线程和消费者线程使用不同的runnable 实现类创建,如果想共享变量必须从外界传过来。

// Producer Class in java
class Producer implements Runnable {
    private final BlockingQueue sharedQueue;
    public Producer(BlockingQueue sharedQueue) {
        this.sharedQueue = sharedQueue;
    } 
    public void run() {
        for (int i = 0; i < 10; i++) {
        try {
            System.out.println("Produced: " + i);
            sharedQueue.put(i);//无需考虑阻塞问题
        } catch (InterruptedException ex) {
            System.out.println(ex);
        }
    }
}

// Consumer Class in Java
class Consumer implements Runnable {
    private final BlockingQueue sharedQueue;
    public Consumer(BlockingQueue sharedQueue) {
        this.sharedQueue = sharedQueue;
    } 
    public void run() {
        while (true) {
            try {
                int i = (Integer) sharedQueue.take();//无需考虑阻塞问题
                System.out.println("Consumed: " + i);
            } catch (InterruptedException ex) {
                System.out.println(ex);
            }
        }
    }
}

public class ProducerConsumerPattern {
    public static void main(String args[]) {
        // Creating shared object
        BlockingQueue sharedQueue = new LinkedBlockingQueue();
        // Creating Producer and Consumer Thread
        Thread prodThread = new Thread(new Producer(sharedQueue));
        Thread consThread = new Thread(new Consumer(sharedQueue));
        prodThread.start();
        consThread.start();
    }
}

2.使用 Object 的 wait()和 notify()实现
PriorityQueue queue = new PriorityQueue(10);

class Consumer extends Thread {
    public void run() {
        while (true) {
            synchronized (queue) {//
                while (queue.size() == 0) {//队列空的条件下阻塞
                try {
                    queue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    queue.notify();
                }
            }
            queue.poll(); // 每次移走队首元素
            queue.notify();//唤醒阻塞的生产者线程
            }
        }
    }
}


class Producer extends Thread {
    public void run() {
        while (true) {
            synchronized (queue) {
                while (queue.size() == 10) {//队列满了的条件下阻塞
                    try {
                        queue.wait();//被阻塞将自动释放锁
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            queue.notify();
                        }
                }
                queue.offer(1); // 每次插入一个元素
                queue.notify();唤醒阻塞的消费者线程
            }
        }
    }
}

3.使用Condition实现
private PriorityQueue queue = newPriorityQueue(10);
private Lock lock = new ReentrantLock();
private Condition notFull = lock.newCondition();
private Condition notEmpty = lock.newCondition();

class Consumer extends Thread {
    public void run() {
    while (true) {
        lock.lock();
        try {
            while (queue.size() == 0) {
                try {
                    notEmpty.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            queue.poll(); // 每次移走队首元素
            notFull.signal();//唤醒生产者线程 与synchronized不同点在于这里通过内置condition 对象
            } finally {
                lock.unlock();
            }
        }
    }
}

class Producer extends Thread {
    public void run() {
        while (true) {
            lock.lock();
            try {
                while (queue.size() == 10) {
                try {
                    notFull.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                queue.offer(1); // 每次插入一个元素
                notEmpty.signal();//唤醒消费者者线程 与synchronized不同点在于这里通过内置condition 对象
            } finally {
                lock.unlock();
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值