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