【多线程】 练习 生产者消费者

需求:使用多个线程实现资源的一存一取交替执行。

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


/*
这是资源类(存放商品信息)
 */
class Commodity{

    private String name ;            //商品名
    private int num = 1;             //商品编号
    private boolean flag = false;    //标记是否已有商品存在
    Lock lock = new ReentrantLock(); //锁

    //这两个对象用来等待和唤醒生产和消费线程
    Condition conpro = lock.newCondition(); //绑定锁的生产者监视器
    Condition concus = lock.newCondition(); //绑定锁的消费者监视器

    public void produce(String name) throws InterruptedException
    {
        lock.lock();  //上锁
        try
        {
            //如果已经有了商品,则无需再生产,生产线程被等待
            while (flag)
                conpro.await();

            this.name = name + " "+num+++"号";
            System.out.println("生产了一个"+this.name);
            flag = true;        //生产一个商品之后,标记为true
            concus.signal();    //唤醒一个消费线程
        }
        finally
        {
            //因为无论如何,在执行完该段代码之后都必须要解锁,因此unlock方法在finally代码段中
            lock.unlock();
        }


    }

    public void consumption() throws InterruptedException
    {
        lock.lock();    //上锁
        try
        {
            //如果此时没有商品,则消费线程被等待
            while (!flag)
                concus.await();
            System.out.println("消费了一个"+this.name);
            flag = false;       //消费掉商品之后,将标记置为false
            conpro.signal();    //消费掉商品之后,唤醒一个生产线程
        }
        finally
        {
            //因为无论如何,在执行完该段代码之后都必须要解锁,因此unlock方法在finally代码段中
            lock.unlock();
        }
    }
}

/*
这是一个生产线程类,通过实现Runnable接口
 */
class Producer implements Runnable{

    Commodity com ; //商品(资源)引用

    public Producer(Commodity com)  //通过构造函数传入一个商品(资源)对象
    {
        this.com = com;
    }

    public void run()   //覆盖run()
    {
        while (true)
        {
            try {
                com.produce("商品");  //调用生产商品的方法
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

/*
这是一个消费线程类,通过实现Runnable接口
 */
class Customer implements Runnable{

    Commodity com ;//商品(资源)引用

    public Customer(Commodity com)  //通过构造函数传入一个商品(资源)对象
    {
        this.com = com;
    }

    public void run()   //覆盖run()
    {
        while (true) {
            try {
                com.consumption();  //调用消费方法
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


/*
主类,完成生产和消费线程的创建和开启
 */
public class UltTest {

    public static void main(String[] args) {

        Commodity com = new Commodity();    //资源对象

        //创建生产、消费对象并传入资源对象
        Producer pro = new Producer(com);
        Customer cus = new Customer(com);

        //创建线程对象并传入实现Runnable接口的类对象
        Thread t1 = new Thread(pro);
        Thread t2 = new Thread(pro);
        Thread t3 = new Thread(cus);
        Thread t4 = new Thread(cus);

        //开启线程
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值