实验报告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();
    }
}
相关推荐
方圆想当图灵3 分钟前
缓存之美:万文详解 Caffeine 实现原理(下)
java·redis·缓存
栗豆包17 分钟前
w175基于springboot的图书管理系统的设计与实现
java·spring boot·后端·spring·tomcat
等一场春雨1 小时前
Java设计模式 十四 行为型模式 (Behavioral Patterns)
java·开发语言·设计模式
酱学编程2 小时前
java中的单元测试的使用以及原理
java·单元测试·log4j
我的运维人生2 小时前
Java并发编程深度解析:从理论到实践
java·开发语言·python·运维开发·技术共享
一只爱吃“兔子”的“胡萝卜”2 小时前
2.Spring-AOP
java·后端·spring
HappyAcmen2 小时前
Java中List集合的面试试题及答案解析
java·面试·list
Ase5gqe2 小时前
Windows 配置 Tomcat环境
java·windows·tomcat
大乔乔布斯2 小时前
JRE、JVM 和 JDK 的区别
java·开发语言·jvm
湫qiu3 小时前
带你写HTTP/2, 实现HTTP/2的编码
java·后端·http