实验报告2-多线程并发

实验报告2-多线程并发

一、实现思路

生产者消费者问题描述了共享固定大小缓冲区的两个线程------即所谓的"生产者"和"消费者"------在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。要求:

1、在缓冲区为空时,消费者不能再进行消费

2、在缓冲区为满时,生产者不能再进行生产

3、在一个线程进行生产或消费时,其余线程不能再进行生产或消费等操作,即保持线程间的同步

4、注意条件变量与互斥锁的顺序

二、实验步骤

Store仓库类

java 复制代码
public class Store {
    // 仓库容量
    private int capacity;
    // 底层数据结构
    private List list = new LinkedList<Object>();
    public int getCapacity() {
        return capacity;
    }
    public List getList() {
        return list;
    }
    // 构造函数,为仓库容量赋值
    protected Store(int capacity) {
        this.capacity = capacity;
    }
}

Producer生产者类

java 复制代码
public class Producer implements Runnable{
​
    //仓库
    private Store store;
​
    //构造方法,实例化仓库
    public Producer(Store store) {
        this.store = store;
    }
​
    @Override
    public void run() {
        while (true){
            produce();
        }
    }
​
    private synchronized void produce() {
        // 仓库未满,生产商品,唤醒消费者
        if (store.getList().size() <store.getCapacity()) {
            // 生产商品
            store.getList().add(new Object());
            // 唤醒消费者
            notifyAll();
            System.out.println(String.format("%s,生产了一件商品,仓库商品数为%d,唤醒消费者",
                Thread.currentThread().getName(),store.getList().size()));
            // 休眠
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 仓库已满,休眠,等待被唤醒
        else {
            try {
                System.out.println(String.format("仓库已满,%s,休眠",Thread.currentThread().getName()));
                wait(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Consumer消费者类

java 复制代码
public class Consumer implements Runnable{

    //仓库
    private Store store;
​
    //构造方法,实例化仓库
    public Producer(Store store) {
        this.store = store;
    }
​
    @Override
    public void run() {
        while (true){
            consume();
        }
    }
​
    private synchronized void consume() {
        // 仓库不为空,消费商品,唤醒生产者
        if (store.getList().size() > 0) {
            // 消费商品
            store.getList().remove(0);
            // 唤醒生产者
            notifyAll();
            System.out.println(String.format("%s,消费了一件商品,仓库商品数为%d,唤醒生产者",
                    Thread.currentThread().getName(),store.getList().size()));
            // 睡眠
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 仓库为空,休眠,等待被唤醒
        else {
            try {
                System.out.println(String.format("仓库为空,%s,休眠",Thread.currentThread().getName()));
                wait(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Test测试类

java 复制代码
public class Test {
    public static void main(String[] args) {
        //实例化新建仓库对象,设置仓库的容量
        Store store = new Store(2);
        //实例化生产者对象
        Producer producer = new Producer(store);
        //实例化消费者对象
        Consumer consumer = new Consumer(store);
​
        //创建生产者线程
        new Thread(producer,"生产者1").start();
        new Thread(producer,"生产者2").start();
        //创建消费者线程
        new Thread(consumer,"消费者1").start();
        new Thread(consumer,"消费者2").start();
    }
}
相关推荐
suweijie7682 小时前
SpringCloudAlibaba | Sentinel从基础到进阶
java·大数据·sentinel
公贵买其鹿3 小时前
List深拷贝后,数据还是被串改
java
xlsw_6 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹7 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭8 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫8 小时前
泛型(2)
java
超爱吃士力架8 小时前
邀请逻辑
java·linux·后端
南宫生8 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石8 小时前
12/21java基础
java
李小白668 小时前
Spring MVC(上)
java·spring·mvc