有谁知道是否有一种可靠的方法来设置生产者消费者类型队列,其中包含以下内容:
1) Producer 最初将三个对象放入队列
2)消费者消费一个项目,在队列中留下两个对象
3) 控制权传回 Producer,Producer 再放一个项目 - (现在 3 个对象再次出现在队列中)
4) 消费者又消费了一件商品,因此循环继续
请注意,我需要手动设置解决方案,而不使用任何界面来完成我正在处理的任务。任何意见,将不胜感激。
线程可以进行这种微调吗?
有谁知道是否有一种可靠的方法来设置生产者消费者类型队列,其中包含以下内容:
1) Producer 最初将三个对象放入队列
2)消费者消费一个项目,在队列中留下两个对象
3) 控制权传回 Producer,Producer 再放一个项目 - (现在 3 个对象再次出现在队列中)
4) 消费者又消费了一件商品,因此循环继续
请注意,我需要手动设置解决方案,而不使用任何界面来完成我正在处理的任务。任何意见,将不胜感激。
线程可以进行这种微调吗?
我可能会做的是有一个相对普通的队列并且还有一个信号量。将信号量初始化为 -2。让生产者在将请求排入队列时增加信号量。让消费者在出队请求之前减少信号量。在计数变为 1 之前,消费者将无法进行递减,因此队列中总会有 2 个未服务的请求。
I hope this solution gives you some help:
解释如下:
两个单独的线程(Producer thread and Consumer thread)
在一个公共队列上相互协调工作(这里我提到了数组)。生产者从一个数据数组中放入三个元素,消费者获取一个并从同一个数组中删除。当数据数组所有元素都放入队列时,消费者只一个一个地获取。put()
并且take()
是在单独的类中定义的同步方法Drop
。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ProducerConsumerExample {
public static final Lock fileLock = new ReentrantLock();
public static final Condition condition = fileLock.newCondition();
public static String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqr"
};
public static List<String> list = new ArrayList<String>();
public static boolean done = false;
public static void main(String[] args) {
Drop drop = new Drop();
Thread tProducer = new Thread(new Producer(drop));
Thread tConsumer = new Thread(new Consumer(drop));
try{
tProducer.start();
tConsumer.start();
}
catch(Exception ie){}
}
}
public class Consumer implements Runnable {
private Drop drop;
public Consumer(Drop drop) {
this.drop = drop;
}
public void run() {
try{
ProducerConsumerExample.fileLock.lock();
for (String message = drop.take();
! message.equals("DONE");
message = drop.take()) {
System.out.format("MESSAGE RECEIVED: %s%n", message);
ProducerConsumerExample.list.remove(0);
if(ProducerConsumerExample.done)
continue;
else{
ProducerConsumerExample.condition.signal();
System.out.println("Consumer is waiting");
ProducerConsumerExample.condition.await();
}
} catch (InterruptedException e) {}
}
}
catch(Exception e){
}
finally{
ProducerConsumerExample.fileLock.unlock();
}
}
}
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Producer implements Runnable {
private Drop drop;
public Producer(Drop drop) {
this.drop = drop;
}
public void run() {
try{
ProducerConsumerExample.fileLock.lock();
Random random = new Random();int check = 3;
for (int i = 0;
i <ProducerConsumerExample.importantInfo.length;
i++) {
if(i<check){
System.out.println("Putting message");
System.out.println(ProducerConsumerExample.importantInfo[i]);
drop.put(ProducerConsumerExample.importantInfo[i]);
}
else{
check = check+3;
i--;
ProducerConsumerExample.condition.signal();
System.out.println("Producer is waiting");
ProducerConsumerExample.condition.await();
}
}
drop.put("DONE");
ProducerConsumerExample.done =true;
ProducerConsumerExample.condition.signal();
System.out.println("Producer is waiting");
ProducerConsumerExample.condition.await();
}
catch(Exception e){
e.printStackTrace();
}
finally{
ProducerConsumerExample.fileLock.unlock();
}
}
}
import java.util.ArrayList;
import java.util.List;
public class Drop {
// Message sent from producer
// to consumer.
private String message;
public synchronized String take() {
System.out.println(ProducerConsumerExample.list.size());
return ProducerConsumerExample.list.get(0);
}
public synchronized void put(String message) {
// Store message.
ProducerConsumerExample.list.add(message);
}
}
Java 7 有一个LinkedTransferQueue听起来像您正在寻找的东西,或者查看父类型BlockingQueue,我相信其中一个会符合要求。
您可以使用 ArrayList 并将容量设置为 3;然后,只要 Producer 执行,就会检查数组大小;如果大小小于 3,只需将值插入 ArrayList 直到大小为 3;如果大小为 3;只需调用notifyAll()方法即可完成。
同样对于Consumer,如果大小为3,则消费其中一个值,并将其从ArrayList中移除;如果大小小于 3,只需调用notifyAll()方法即可完成。
简而言之,这基本上就是它的工作原理;实施将取决于您计划用它实现的目标。
希望这可以帮助。