Java 许多生产者和许多消费者。让最后一个生产者活着杀死消费者
我有一个标准的生产者消费者问题。生产者将数据放入堆栈(缓冲区),消费者接收数据 我希望有许多生产者和消费者 问题是我只想让最后一个活着的制作人能够调用Java 许多生产者和许多消费者。让最后一个生产者活着杀死消费者,java,multithreading,producer-consumer,Java,Multithreading,Producer Consumer,我有一个标准的生产者消费者问题。生产者将数据放入堆栈(缓冲区),消费者接收数据 我希望有许多生产者和消费者 问题是我只想让最后一个活着的制作人能够调用b.stop() for(int i = 0; i < 10; i++){ try{ // sleep((int)(Math.random() * 1)); }catch(Exception e){e.printStackTrace();} b.
b.stop()
for(int i = 0; i < 10; i++){
try{
// sleep((int)(Math.random() * 1));
}catch(Exception e){e.printStackTrace();}
b.put((int) (Math.random()* 10));
System.out.println("i = " + i);
}
b.stop();
他们应该死了,所以我让方法stop()但它不起作用
代码正在运行,请检查它
import java.util.Stack;
public class Buffer {
private static int SIZE = 4;
private int i;//number of elements in buffer
public Stack<Integer> stack;
private volatile boolean running;
public Buffer() {
stack = new Stack<>();
running = true;
i = 0;
}
synchronized public void put(int val){
while (i >= SIZE) {
try {
System.out.println("Buffer full, producer waits");
wait();
} catch (InterruptedException exc) {
exc.printStackTrace();
}
}
stack.push(val);//txt = s;
i++;
System.out.println("Producer inserted " + val + " memory: " + i);
if(i - 1 == 0)
notifyAll();
System.out.println(stack);
}
public synchronized Integer get(Consumer c) {
while (i == 0) {
try {
System.out.println(c + ": no data to take. I wait. Memory: " + i);
wait();
} catch (InterruptedException exc) {
exc.printStackTrace();
}
}
if(running){
int data = stack.pop();
i--;
System.out.println(c+ ": I took: " + data +" memory: " + i);
System.out.println(stack);
if(i + 1 == SIZE){//if the buffer was full so the producer is waiting
notifyAll();
System.out.println(c + "I notified producer about it");
}
return data;}
else
return null;
}
public boolean isEmpty(){
return i == 0;
}
public synchronized void stop(){//I THOUGH THIS WOULD FIX IT~!!!!!!!!!!!!!!
running = false;
notifyAll();
}
public boolean isRunning(){
return running;
}
}
在
stop
方法中,您将running
设置为false
,但只要i==0,while循环就会运行。将i
设置为与零不同的值,它应该会修复它
顺便说一句,我不明白为什么有一个正在运行
变量和一个单独的I
变量,这实际上是保持线程运行的变量。您必须意识到的是,您的线程可能在两个位置之一等待:
在wait
循环中,使用i==0
——在这种情况下,notifyall
将把它们全部踢出。但是,如果i
仍然是0
,他们将直接返回等待
等待对对象的独占访问(即等待同步
方法)-在这种情况下(如果您解决了上面的问题1,锁将被释放),它们将直接进入而(i==0)
循环
我建议您将while(I==0)
循环更改为while(running&&I==0)
。这将解决您的问题。由于您的正在运行
标志(正确地)易失性
应整齐退出。我将重新考虑您的设计。班级应该有一套连贯的职责;让一个类负责队列外的两个消费对象,同时也负责关闭其他消费对象,这似乎是您想要分离的事情。为了回答,只让最后一个活着的生产者能够调用b.stop()
您应该向包含生产者数量的缓冲区添加一个AtomicInteger
,并在其构造函数中进行每个生产者调用b.start()
(递增)
这样,您可以在b.stop()
中减小它,并且只有当它变为零时,running
才应该设置为false
我在帖子中忘了更改它。。我有while(running&&I==0)
但问题是我只想让最后一个活着的制作人能够调用b.stop()
import java.util.Stack;
public class Buffer {
private static int SIZE = 4;
private int i;//number of elements in buffer
public Stack<Integer> stack;
private volatile boolean running;
public Buffer() {
stack = new Stack<>();
running = true;
i = 0;
}
synchronized public void put(int val){
while (i >= SIZE) {
try {
System.out.println("Buffer full, producer waits");
wait();
} catch (InterruptedException exc) {
exc.printStackTrace();
}
}
stack.push(val);//txt = s;
i++;
System.out.println("Producer inserted " + val + " memory: " + i);
if(i - 1 == 0)
notifyAll();
System.out.println(stack);
}
public synchronized Integer get(Consumer c) {
while (i == 0) {
try {
System.out.println(c + ": no data to take. I wait. Memory: " + i);
wait();
} catch (InterruptedException exc) {
exc.printStackTrace();
}
}
if(running){
int data = stack.pop();
i--;
System.out.println(c+ ": I took: " + data +" memory: " + i);
System.out.println(stack);
if(i + 1 == SIZE){//if the buffer was full so the producer is waiting
notifyAll();
System.out.println(c + "I notified producer about it");
}
return data;}
else
return null;
}
public boolean isEmpty(){
return i == 0;
}
public synchronized void stop(){//I THOUGH THIS WOULD FIX IT~!!!!!!!!!!!!!!
running = false;
notifyAll();
}
public boolean isRunning(){
return running;
}
}
public class Producer extends Thread {
private Buffer b;
public Producer(Buffer b) {
this.b = b;
}
public void run(){
for(int i = 0; i < 10; i++){
try{
// sleep((int)(Math.random() * 1));
}catch(Exception e){e.printStackTrace();}
b.put((int) (Math.random()* 10));
System.out.println("i = " + i);
}
b.stop();
}
}
public class Consumer extends Thread {
Buffer b;
int nr;
static int NR = 0;
public Consumer(Buffer b) {
this.b = b;
nr = ++NR;
}
public void run() {
Integer i = b.get(this);
while (i != null) {
System.out.println(nr + " I received : " + i);
i = b.get(this);
}
System.out.println("Consumer " + nr + " is dead");
}
public String toString() {
return "Consumer " + nr + ".";
}
}
public class Main {
public static void main(String[] args) {
Buffer b = new Buffer();
Producer p = new Producer(b);
Consumer c1 = new Consumer(b);
Consumer c2 = new Consumer(b);
Consumer c3 = new Consumer(b);
p.start();
c1.start();c2.start();c3.start();
}
}