Java进阶基础-多线程之间的通讯,jdk1.5之后的新特性,解决多线程之间的生产消费模式

package idea.threadtest;

/*
要求:多生产者多消费者----生产消费模式
生产一个,消费一个,多线程同时进行。

* jdk1.5版本之后新特新
* 用Lock替代了同步代码块,用Condition替代await
* */
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class story15 {
    //商品名称
    private String name;
    //标号标识位,本例作用不大,忽略。
    private int sum;
    //控制开关,按照存入取出模式,存一个取一个。
    private boolean flag = false;
    //多线程统一锁控制
    private Lock lock = new ReentrantLock();

    //用同一锁对象创建condition对象,服务员和消费者,用来调用等待和唤醒功能。
    //服务员condition对象
    Condition condition_waiter = lock.newCondition();
    //消费者condition对象
    Condition condition_customer = lock.newCondition();

    //商品上架方法
    public void add(){
        try{
            //上锁,相当于jdk1.5版本之前的synchronized
            lock.lock();
            //虚幻判断标记
            while(flag)
                //如果为true,那说明货架上有商品,服务员线程等待。
                    condition_waiter.await();
            //如果为false,继续向下执行,服务员线程开始添加商品。
                this.setName("2号商品");
                this.setSum(sum+1);
                //输出打印
                System.out.println(Thread.currentThread().getName()+"哦豁,添加了"+this.getSum()+"到货架上。");
                //重置标识为真,添加商品上架之后
                flag = true;
                //唤醒在线程池中等待的第一消费者线程。
                condition_customer.signal();
                //这是一个让本线程放弃执行权的方法
//                Thread.yield();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放锁的操作是必须进行的,所以需要在finally中存放。
            lock.unlock();
        }
    }
    //这是消费者消费的方法
    public void sale(){
        try {
            //上锁,这里flag就是为共享操作数据了
            lock.lock();
            //循环判断标识位
            while(!flag)
                //如果标识为为假,那说明货架上没有物品,需要等待服务员上货
                condition_customer.await();
            //如果有货物,说明无需等待,直接打印即可。
                System.out.println(Thread.currentThread().getName()+"哦豁,刚刚消费了第"+sum+"号商品,请服务员及时添加。");
                //这个sum是用来判断商品编号的,本例中可以忽略
                sum--;
                //消费完成,重置标识为false,说明货架上没货了
                flag = false;
                //此时需要提醒服务员线程上货,即释放服务员线程
                condition_waiter.signal();
//                Thread.yield();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放资源
            lock.unlock();
        }
    }
    public String getName() {
        return name;
    }
    public int getSum() {
        return sum;
    }
    public void setSum(int sum) {
        this.sum = sum;
    }
    public void setName(String name) {
        this.name = name;
    }
}

你可能感兴趣的:(Java基础进阶,多线程,java,并发编程,jdk)