栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

第6组markdown

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

第6组markdown

用java多线程实现生产者消费者同步问题 组员:师浩东 魏昕宇 郑旭根

目录
  • 用java多线程实现生产者消费者同步问题
  • 组员:师浩东 魏昕宇 郑旭根
    • 一、思路分析
    • 二、java代码实现与思路
      • 流程图:
      • 1.创建仓库类
      • 2.创建生产者类
      • 3.创建消费者类
      • 4.创建测试类实现代码


一、思路分析

首先由于是生产者生产出产品,消费者才能消费
所以生产者消费者问题,实际上主要包含了两类线程。
一类是生产者线程用于生产产品,一类是消费者线程用于消费产品。
为解决这个问题,我们假设有一个仓库,生产者生产出产品之后就直接放在仓库里,并不需要关心消费者的行为,消费者只需要从仓库中消费产品即可,并不需要关心生产者的行为

二、java代码实现与思路 流程图:

1.创建仓库类

所以首先我们新建一个类来作为仓库,其中肯定需要定义放入产品和取出产品的方法

其中为了防止同一件产品被多名消费者消费,需要用synchronized关键字给取的方法上锁,也就是说,当有一个消费者线程抢占到CPU执行权之后,其他线程就不能调用消费(put)这个方法。

代码如下:

public class Box {
    //定义一个成员变量,表示第x个产品
    private int product;
    //定义一个成员变量,表示仓库的状态
    private boolean state=false;
    //上锁
    //一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞
    public synchronized void put(int product){
        //如果有产品,等待消费
        if (state==true){
            try{
                wait();
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
        //如果没有产品,等待生产
        this.product=product;
        System.out.println("生产者将第"+this.product+"件产品放入仓库");
        //消费完毕之后,修改仓库状态
        state=true;
        //唤醒其他等待的线程
        notifyAll();
    }
    public synchronized void get(){
        //如果没有产品,等待生产
        if (!state){
             try {
                 wait();
             }catch (InterruptedException e){
                 e.printStackTrace();
             }
        }
        System.out.println("消费者消费第"+this.product+"件产品");
        //消费完毕之后,修改仓库状态
        state=false;
        //解锁唤醒其他等待线程
        notifyAll();
    }
}

2.创建生产者类

创建生产者类实现了Runnable接口,在类里边定义了带参构造方法,参数类型为仓库类
这样就可以在主方法执行时,启动线程,调用这个类中的run方法,然后生产时直接可以调用仓库类中的put方法把产品放入仓库。

public class Producer implements Runnable{
    private Box box;
    public Producer(Box b){
        this.box=b;
    }
    @Override
    public void run() {
        //假设这个生产者一天只能生产五件给消费者
        for (int i=1;i<=5;i++){
            box.put(i);
        }
    }
}

3.创建消费者类

创建消费者类实现了Runnable接口,在类里边定义了带参构造方法,参数类型为仓库类
这样就可以在主方法执行时,启动线程,调用这个类中的run方法,然后消费时直接可以调用仓库类中的get方法消费产品。

public class Customer implements Runnable{
    private Box box;
    public Customer(Box box){
        this.box=box;
    }
    @Override
    public void run() {
        while (true){
            box.get();
        }
    }
}


4.创建测试类实现代码
public class Main {
    public static void main(String[] args) {
        //创建仓库对象,作为共享区域
        Box box=new Box();
        //创建生产者对象,把仓库作为构造方法的参数传递,因为在这个类中要调用存储产品的操作
        Producer producer=new Producer(box);
        //创建消费者对象,把仓库作为构造方法参数的传递,因为在这个类中要调用获取产品的操作
        Customer customer=new Customer(box);
        //创建线程对象,分别把生产者对象和消费者对象作为构造方法参数传递
        Thread thread1=new Thread(producer);
        Thread thread2=new Thread(customer);
        thread1.start();
        thread2.start();
    }
}

运行结果为:

"D:IDEAIntelliJ IDEA 2019.3.3jbrbinjava.exe" "-javaagent:D:IDEAIntelliJ IDEA 2019.3.3libidea_rt.jar=5125:D:IDEAIntelliJ IDEA 2019.3.3bin" -Dfile.encoding=UTF-8 -classpath D:IdeaJavaCode语法2outproduction语法2 多线程.Main
生产者将第1件产品放入仓库
消费者消费第1件产品
生产者将第2件产品放入仓库
消费者消费第2件产品
生产者将第3件产品放入仓库
消费者消费第3件产品
生产者将第4件产品放入仓库
消费者消费第4件产品
生产者将第5件产品放入仓库
消费者消费第5件产品

根据结果可以看出,运行结果确实是生产者生产一个产品消费者就可以消费一个产品,并且没有出现几个消费者同时消费一个产品的情况,所以此代码完成了生产者消费者问题。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/305383.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号