第6组markdown
作者:互联网
用java多线程实现生产者消费者同步问题
组员:师浩东 魏昕宇 郑旭根
目录
一、思路分析
首先由于是生产者生产出产品,消费者才能消费
所以生产者消费者问题,实际上主要包含了两类线程。
一类是生产者线程用于生产产品,一类是消费者线程用于消费产品。
为解决这个问题,我们假设有一个仓库,生产者生产出产品之后就直接放在仓库里,并不需要关心消费者的行为,消费者只需要从仓库中消费产品即可,并不需要关心生产者的行为
二、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:\IDEA\IntelliJ IDEA 2019.3.3\jbr\bin\java.exe" "-javaagent:D:\IDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=5125:D:\IDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\IdeaJavaCode\语法2\out\production\语法2 多线程.Main
生产者将第1件产品放入仓库
消费者消费第1件产品
生产者将第2件产品放入仓库
消费者消费第2件产品
生产者将第3件产品放入仓库
消费者消费第3件产品
生产者将第4件产品放入仓库
消费者消费第4件产品
生产者将第5件产品放入仓库
消费者消费第5件产品
根据结果可以看出,运行结果确实是生产者生产一个产品消费者就可以消费一个产品,并且没有出现几个消费者同时消费一个产品的情况,所以此代码完成了生产者消费者问题。
标签:markdown,消费者,仓库,件产品,生产者,线程,public 来源: https://blog.csdn.net/weixin_49053303/article/details/120587769