使用java Condition构建生产者消费者

1.Condition介绍

在上一篇文章中曾经提到对象的wait和notify方法,condition类其实就是这种方法的一种替代性产物。
Condition对象是同Lock结合使用,由Lock进行创建,并且condition.await的调用者必须获取lock,在await时该线程自动释放锁,当其被其他线程signal之后再重新获取锁,这同上一篇博客中提到的sychronized的用法类似。

2. 基于Condition的生产者消费者程序

(貌似ArrayBlockingQueue)这里使用notFull和notEmpty表示链表中元素有无的一个条件,具体代码如下:

package concurrency;

/**
 * Created by wangxiaoyi on 15/11/18.
 */

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class ProducerAndConsumer2 {

    private List<Integer> data = new LinkedList<>();
    private static final int MAX_DATA_LEN = 10;
    private Lock lock = new ReentrantLock();
    private Condition notEmpty = lock.newCondition();// 非空条件
    private Condition notFull = lock.newCondition();// 非满条件


    class Producer implements Runnable {

        private int pid = 0;

        public Producer(int pid){
            this.pid = pid;
        }

        public void run() {
            try {
                while (!Thread.currentThread().isInterrupted()) {


                    lock.lock();

                    while (data.size() >= MAX_DATA_LEN) {
                        System.out.println("Producer" + pid + " waiting ! size : " + data.size());
                        notFull.await(); // 等待notFull.signal唤醒
                    }

                    try{
                        data.add(pid);
                        notEmpty.signal(); // 唤醒notEmpty.await()线程
                        System.out.println("Producer" + pid + " add " + pid + " size: " + data.size());

                    }finally {
                        lock.unlock();
                    }

                    Thread.sleep(500);
                }
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
        }
    }


    class Consumer implements Runnable{
        private int cid = 0;

        public Consumer(int cid){
            this.cid = cid;
        }

        public void run(){
            try {
                while (!Thread.currentThread().isInterrupted()) {


                    lock.lock();

                    while (data.isEmpty()) {
                        System.out.println("Consumer" + cid + " waiting, data size : " + data.size());
                        notEmpty.await();
                    }

                    try{
                        int pid = data.remove(0);
                        notFull.signal();
                        System.out.println("Consumer" + cid + " consuming data " + pid +" data size : " + data.size());

                    }finally {
                        lock.unlock();
                    }

                    Thread.sleep(500);
                }
            }catch (InterruptedException ie){
                ie.printStackTrace();
            }
        }
    }


    public void start(){



        ExecutorService executor = Executors.newCachedThreadPool();

        for(int i = 0; i < 5; ++ i){
            executor.submit(new Producer(i));
            executor.submit(new Consumer(i));
        }

        try {
            Thread.sleep(10*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        executor.shutdownNow();
    }


    public static void main(String []args){

        new ProducerAndConsumer2().start();

    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值