实验报告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();
    }
}
相关推荐
风铃儿~12 分钟前
Java面试高频问题(26-28)
java·算法·面试
IT瘾君20 分钟前
Java基础:认识注解,模拟junit框架
java·开发语言·junit
风象南21 分钟前
SpringBoot中3种内容协商策略实现
java·spring boot·后端
IT瘾君23 分钟前
JavaWeb:Web介绍
java·web
不秃的开发媛32 分钟前
前端技术Ajax入门
java·开发语言·前端
大家都说我身材好42 分钟前
如何优化字符串替换:四种实现方案对比与性能分析
java·字符串
xixixin_1 小时前
【uniapp】vue2 搜索文字高亮显示
java·服务器·前端·uni-app·交互·文字高亮
左灯右行的爱情1 小时前
深入理解 G1 GC:已记忆集合(RSet)与收集集合(CSet)详解
java·jvm·后端·juc
珹洺1 小时前
Jsp技术入门指南【十】IDEA 开发环境下实现 MySQL 数据在 JSP 页面的可视化展示,实现前后端交互
java·运维·前端·mysql·intellij-idea·jsp
爱的叹息1 小时前
mybatis-plus里的com.baomidou.mybatisplus.core.override.MybatisMapperProxy 类的详细解析
java·tomcat·mybatis