题目:有多个生产者往一个有界队列中添加消息,多个消费者消费该消息;
要求:在队列未满之前,消费者不消费消息,当队列未空之前,生产者不生产消息
我的思路:
首先,多个生产者之间是互斥的,避免把队列撑满溢出,需要用到锁,synchronized
其次:生产者和消费者之间是同步的,即:队列是否满
ok:直接上代码:
package com.sf.interview.manyProduct;
import java.util.concurrent.ArrayBlockingQueue;
public class TaskThead implements Runnable{
private ArrayBlockingQueue<String> queue;
private Object lock;
private int queueLength;
/**
* 被唤醒后是否执行操作
*/
private static volatile Integer flag=1;
/**
* 线程类型 1 表示生产者 0表示消费者
*/
private int type;
@Override
public void run() {
while(true){
synchronized(lock){
if(type==1){
doProduct();
}else{
doConsumer();
}
}
}
}
private void doProduct() {
//如果标志位为1 表示执行添加元素操作
if(flag==1){
if(queue.size()<queueLength){
String name = Thread.currentThread().getName();
String str="线程名称:"+name;
try {
System.out.println("线程:"+name+"向队列中添加元素:"+str);
queue.put(str);
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}//如果此时标志位是1 但是队列元素已经满了,需要修改标志位为0 切唤醒其他线程
else{
System.out.println(Thread.currentThread().getName()+"准备修改flag的值为0");
flag=0;
System.out.println(Thread.currentThread().getName()+"修改之后flag的值为:"+flag);
lock.notifyAll();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}else{
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void doConsumer() {
if(flag==0){
//如果队列元素不为空 就继续消费
if(queue.size()!=0){
try {
String str = queue.poll();
String name = Thread.currentThread().getName();
System.out.println("消费者线程:"+name+"消费消息:"+str);
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}//如果标志位0 并且队列已经没有元素了,需要唤醒所有的生产者,并且把标会位修改为1
else{
try {
System.out.println(Thread.currentThread().getName()+"准备修改flag的值为1");
flag=1;
System.out.println(Thread.currentThread().getName()+"修改后的值是:"+flag);
lock.notifyAll();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}//如果标志位不是0 表示消费者需要继续沉睡
else{
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
int length=10;
Object lock = new Object();
ArrayBlockingQueue<String> queue=new ArrayBlockingQueue<>(length);
int flag=1;
//new TaskThead(queue, lock, length, flag, 1);
new Thread(new TaskThead(queue, lock, length, 1),"生产者1").start();
new Thread(new TaskThead(queue, lock, length, 1),"生产者2").start();
new Thread(new TaskThead(queue, lock, length, 1),"生产者3").start();
new Thread(new TaskThead(queue, lock, length, 0),"消费者1").start();
new Thread(new TaskThead(queue, lock, length, 0),"消费者2").start();
new Thread(new TaskThead(queue, lock, length, 0),"消费者3").start();
}
public TaskThead(ArrayBlockingQueue<String> queue,
Object lock,
int queueLength,int type) {
this.queue = queue;
this.lock = lock;
this.queueLength = queueLength;
this.type=type;
}
}
说明:
类里面flag是用来表示被唤醒后是否执行操作和type有关系
type用来表示是生产者线程还是消费者线程
type=0表示是消费者线程,1表示是生产者线程
结果输出如下:
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
生产者3准备修改flag的值为0
生产者3修改之后flag的值为:0
消费者线程:消费者1消费消息:线程名称:生产者1
消费者线程:消费者1消费消息:线程名称:生产者1
消费者线程:消费者1消费消息:线程名称:生产者1
消费者线程:消费者1消费消息:线程名称:生产者3
消费者线程:消费者2消费消息:线程名称:生产者3
消费者线程:消费者2消费消息:线程名称:生产者3
消费者线程:消费者2消费消息:线程名称:生产者3
消费者线程:消费者2消费消息:线程名称:生产者3
消费者线程:消费者2消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者3准备修改flag的值为1
消费者3修改后的值是:1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
生产者1准备修改flag的值为0
生产者1修改之后flag的值为:0
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者1消费消息:线程名称:生产者1
消费者线程:消费者1消费消息:线程名称:生产者1
消费者线程:消费者1消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者2准备修改flag的值为1
消费者2修改后的值是:1
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
生产者3准备修改flag的值为0
生产者3修改之后flag的值为:0
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者3准备修改flag的值为1
消费者3修改后的值是:1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
生产者1准备修改flag的值为0
生产者1修改之后flag的值为:0
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者2准备修改flag的值为1
消费者2修改后的值是:1
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者2向队列中添加元素:线程名称:生产者2
线程:生产者2向队列中添加元素:线程名称:生产者2
线程:生产者2向队列中添加元素:线程名称:生产者2
线程:生产者2向队列中添加元素:线程名称:生产者2
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
线程:生产者1向队列中添加元素:线程名称:生产者1
生产者1准备修改flag的值为0
生产者1修改之后flag的值为:0
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者2消费消息:线程名称:生产者2
消费者线程:消费者2消费消息:线程名称:生产者2
消费者线程:消费者2消费消息:线程名称:生产者2
消费者线程:消费者2消费消息:线程名称:生产者2
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者线程:消费者2消费消息:线程名称:生产者1
消费者2准备修改flag的值为1
消费者2修改后的值是:1
线程:生产者2向队列中添加元素:线程名称:生产者2
线程:生产者2向队列中添加元素:线程名称:生产者2
线程:生产者2向队列中添加元素:线程名称:生产者2
线程:生产者2向队列中添加元素:线程名称:生产者2
线程:生产者2向队列中添加元素:线程名称:生产者2
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
线程:生产者3向队列中添加元素:线程名称:生产者3
生产者3准备修改flag的值为0
生产者3修改之后flag的值为:0
消费者线程:消费者3消费消息:线程名称:生产者2
消费者线程:消费者3消费消息:线程名称:生产者2
消费者线程:消费者3消费消息:线程名称:生产者2
消费者线程:消费者3消费消息:线程名称:生产者2
消费者线程:消费者3消费消息:线程名称:生产者2
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
消费者线程:消费者3消费消息:线程名称:生产者3
第一次写博客,有不足的地方,请指正,谢谢