线程经典问题 生产者消费者 jdk 1.5后解决办法 lock 和condition

package 线程;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * jdk 1.5 版本后 利用 lock 和 condition 解决生产者和消费者问题
 * Lock 接口的实现子类 就相当于 sychronized 的方法或代码块 使同时只能有一个线程反问,
 * Lock 是 显示的 加锁和解锁,还允许锁在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁,避免了死锁
 *  condition 类 就是 synchronized 中的那个具有锁功能的对象 ,
 *  condition 可以有多个 ,组着这与 lock 使用
 *  但是 一个 condition 的 await(等待)方法只能被他自己的 signal 和 signalAll 方法唤醒
 *  当 线程 A 调用了 一个 condition 对象 C 的 await 方法时 相当于持有了这个 condition 的锁,
 *  只有别的线程 B 调用  condition 对象C  的 signal 和 signalAll 方法才可唤醒 线程A
 *
 */
public class ProducerAndConsumer2 {

    public static void main(String[] args) {
        EggBox2 eb = new EggBox2(9);

        Producers2 p = new Producers2(eb);
        Producers2 p1 = new Producers2(eb);

        Consumers2 c = new Consumers2(eb);
        Consumers2 c1 = new Consumers2(eb);
        new Thread(p).start();
        new Thread(p1).start();

        new Thread(c).start();
        new Thread(c1).start();

    }

}

class Egg2 {
    public int id;

    public Egg2(int id) {
        this.id = id;
    }
}

class EggBox2 {
    private Lock lock = new ReentrantLock();
    private Condition condition_pro = lock.newCondition(); // 生产者的锁
    private Condition condition_con = lock.newCondition();// 消费者的锁

    public EggBox2(int size) {
        eggs = new Egg2[size];
    }

    int num = 0;
    private Egg2[] eggs;

    public int getSize() {
        return eggs.length;
    }

    public void push(Egg2 g) {
        lock.lock(); // 手动给该方法加锁 需要在方法最后边解锁
        try {

            while (num >= eggs.length) {
                try {
                    condition_pro.await();// 使 消费者线程 在 condition_pro上等待
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            eggs[num++] = g;
            System.out.println("the producer make egg --total--" + num);
            condition_con.signal (); // 唤醒在 condition_con 上等待的所有线程
        } finally {

            lock.unlock(); // 解锁
        }
    }

    public Egg2 pop() {
        lock.lock();
        try {
            while (num <= 0) {
                try {
                    condition_con.await(); // 使 消费者线程 在 condition_con上等待
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            Egg2 egg = eggs[--num];
            System.out.println("the consumer eat the egg-------total---" + num);
            condition_pro.signal (); // 唤醒在 condition_pro 上等待的所有线程
            return egg;
        } finally {
            lock.unlock();
        }
    }
}

class Producers2 implements Runnable {
    private EggBox2 eb;

    public Producers2(EggBox2 eb) {
        this.eb = eb;
    }

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            eb.push(new Egg2(i));

            try {
                Thread.sleep((int) Math.random() * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

class Consumers2 implements Runnable {
    private EggBox2 eb;

    public Consumers2(EggBox2 eb) {
        this.eb = eb;
    }

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            Egg2 egg = eb.pop();

            try {
                Thread.sleep((int) Math.random() * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值