如果你曾学习过多线程那么你对生产者消费者模式想必是非常的熟悉,
大致意思是一个仓库有一个商品,有多个生产者和多个消费者,从生产者中间随机取出一位生产者去生产该产品,当产品生产到一定的数量的时候,此时所有的生产者都停止生产该产品,接下来轮到消费者开始消费,从众多消费者之间随机抽取一位消费者去消费该产品,当产品消费完成之后,所有的消费者都会停止消费该产品,接下来轮到生产者.......
个人思路:由于生产者和消费者都是一个个子任务,所以生产功能和消费功能都需要定义,主要还需要一个商品,这样我们可以把商品(一个变量),生产功能,消费功能都放在一个类里面去定义,然后创建一个生产者的类和一个消费者的类去继承thread类来创建多个生产者和消费者,怎么把生产者里面赋予生产功能?以及怎么把消费者赋予消费功能?很简单,可以创建一个接口把生产功能和消费功能都重写,也可以把商品的类的实例化传到生产者和消费者里面,然后再调用函数
接下来如何实现生产者生产到最大值之后开始等待?和消费者消费到0之后的等待?用wait()方法就行
当线程进行等待之后怎么实现通知唤醒?使用notifyAll()就行
接下来需要聊一聊当线程等待之后此时线程的状态。当线程执行完wait()之后,就会进入等待状态,那么这个状态有什么意义呢?意义就是会失锁。
失锁意味着什么?意味着当前线程不能一直霸占cpu,需要和其它线程重新一起抢占cpu资源,当调用notifyAll(),处在等待队列中的线程会被唤醒,锁会重新被加上
聊完之后直接上代码:
这是商品类:
package gg;
public class sum {
private int goods;//货物
private int max;//最大值
public sum(int max) {//设置最大值
// TODO 自动生成的构造函数存根
this.max=max;
}
public synchronized void push(){//生产功能
System.out.println(Thread.currentThread().getName()+"生产者开始......");
while(goods==max){//当达到最大值进入等待队列//为什么用while?就是线程还在运行,但是处于等待状态
try {
wait();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
goods++;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
notifyAll();//唤醒所有线程
System.out.println(Thread.currentThread().getName()+"生产数+1剩余商品"+this.goods);
}
public synchronized void pop(){//消费功能
System.out.println(Thread.currentThread().getName()+"消费者开始消费............");
while(goods==0){//当达到最小值进入等待队列
try {
wait();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
goods--;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
notifyAll();//唤醒所有线程
System.out.println(Thread.currentThread().getName()+"消费数-1剩余商品"+this.goods);
}
}
接下来是生产者类:
package gg;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class producer extends Thread {//生产者类
sum s;
public producer(sum s) {//传入sum类实例
super();
this.s = s;
}
@Override
public void run() {
// TODO 自动生成的方法存根
while(!interrupted())
s.push();
}
public static void main(String[] args) {
sum s=new sum(10);
ExecutorService ex=Executors.newFixedThreadPool(10);
for(int i=0;i<10;i++){
if(i<=4){
ex.execute(new consumer(s));
}else{
ex.execute(new producer(s));
}
}
}
}
接下来是消费者类:
package gg;
public class consumer extends Thread {
sum s=null;
public consumer(sum s) {//传入商品类
super();
this.s = s;
}
@Override
public void run() {
// TODO 自动生成的方法存根
while(!interrupted())
s.pop();
}
}
这只是个简易的生产者消费者模式,还可以继续优化,我就不多继续聊了
喜欢的记得点个关注哟!