Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
生产者-消费者同步Java异常行为 import java.util.ArrayList; 公共班机{ 公共静态void main(字符串[]args){ 生产商=新生产商(“生产商”); 消费者[]消费者=新消费者[1]; for(int i=0;i_Java_Multithreading - Fatal编程技术网

生产者-消费者同步Java异常行为 import java.util.ArrayList; 公共班机{ 公共静态void main(字符串[]args){ 生产商=新生产商(“生产商”); 消费者[]消费者=新消费者[1]; for(int i=0;i

生产者-消费者同步Java异常行为 import java.util.ArrayList; 公共班机{ 公共静态void main(字符串[]args){ 生产商=新生产商(“生产商”); 消费者[]消费者=新消费者[1]; for(int i=0;i,java,multithreading,Java,Multithreading,当你有一个字段,JIT可以检测到一个线程没有改变时,它可以内联它。这意味着,也许有一天,它看到一个值被另一个线程改变了,但它从来没有看到另一个线程的改变 您可以使字段不稳定,这或多或少会起作用,但更好的解决方案是使用具有线程安全增量和减量的AtomicInteger 更多信息。您如何确保对emptyCount和fillCount的访问是线程安全的?是否有任何理由使一个线程中的更改对另一个线程可见?您是否尝试过改为使用AtomicInteger?我最初使用了emptyCount和fillCount

当你有一个字段,JIT可以检测到一个线程没有改变时,它可以内联它。这意味着,也许有一天,它看到一个值被另一个线程改变了,但它从来没有看到另一个线程的改变

您可以使字段不稳定,这或多或少会起作用,但更好的解决方案是使用具有线程安全增量和减量的AtomicInteger


更多信息。

您如何确保对
emptyCount
fillCount
的访问是线程安全的?是否有任何理由使一个线程中的更改对另一个线程可见?您是否尝试过改为使用AtomicInteger?我最初使用了emptyCount和fillCount Is Integer对象,并对它们进行了同步,但我还是继续了它将尝试AtomicIntegers记住只在对象的
final
引用上进行同步。在更改的引用上进行同步不会达到您认为的效果;)现在多谢了。我也让多个生产者和消费者工作,但工作不如我希望的那么顺利。就像一个进程一次在缓冲区上执行5个以上的操作。我想这是我无法控制的,因为你的消费者(和生产者)如果您正忙着等待,则当每个生产者/消费者有两个空闲逻辑CPU时,您的解决方案将工作得最好。如果您没有那么多CPU,您应该期望获得显著的延迟。更具可扩展性的解决方案是使用阻塞队列或执行器。
import java.util.ArrayList;


public class Main {
public static void main(String[] args) {
    Producer producer = new Producer("Producer ");
    Consumer[] consumers = new Consumer[1];

    for (int i = 0; i < consumers.length; i++) {
        consumers[i] = new Consumer(producer,"Consumer " + i);
    }
    producer.start();
    for (int i = 0; i < consumers.length; i++) {

        consumers[i].start();
    }
}
}



class Producer extends Thread{

public ArrayList<Integer> buffer;
public int bufferSize = 20;
int fillCount = 0;
int emptyCount = bufferSize;
Integer item;

public Producer(String name) {
    super(name);
    buffer = new ArrayList<>(bufferSize);
}
public void run() {
    while(true) {
        System.out.println("Producing");
        item = new Integer(1000);
        downEmpty();
        addItemtoBuffer();
        increaseFill();

    }
}
private void addItemtoBuffer() {
    synchronized (buffer) {
        buffer.add(item);
        System.out.println("Produced " + getName() + fillCount + " " + emptyCount);
    }
}
private void downEmpty() {
    while(emptyCount <= 0) {
                    //Busy Waiting when buffer is full
        //System.out.println("EmptyCount " + emptyCount);
    }
    --emptyCount;

}
private void increaseFill() {
    ++fillCount;
}
}

class Consumer extends Thread{

private Producer producer;
private ArrayList<Integer> buffer;
public Consumer(Producer producer, String name) {
    super(name);
    this.producer = producer;
    buffer = producer.buffer;
}
public void run() {
    while(true) {
        downFill();
        consume();
        increaseEmpty();
    }
}
private void downFill() {

    while(producer.fillCount <= 0) {
                    //Busy Waiting when buffer is empty
        //System.out.println("fillCount" + producer.fillCount + " EmptyCount" + producer.emptyCount);
    }
    --producer.fillCount;

}
private void increaseEmpty() {
    ++producer.emptyCount;
}
private void consume() {
    synchronized (buffer) {
        buffer.remove(buffer.size()-1);
        System.out.println("Consumed");
    }


}
}