java - 需要帮助找出 Java 中的基本多线程代码有什么问题(多个生产者 - 一个消费者)

标签 java multithreading

<分区>

运行这段代码时,我得到了大量(对我而言)无意义的异常。不知道我在哪里会犯错误...... 基本上我希望我的生产者将 alpha 字符放入缓冲区,消费者从缓冲区中获取它们并打印。我刚开始学习多线程,我不知道这段代码中的潜在问题是什么。我试图实现类示例。如果这是一个愚蠢的问题,我真的很抱歉......

public class Driver {
    public static void main(String[] args) {
        new Consumer("Consumer1");
        new Consumer("Consumer2");
        new Consumer("Consumer3");
        new Producer("Producer1");
    }   
}
public class Producer implements Runnable{

    private Buffer buf = null;

    public Producer(String name){
        buf = Buffer.getInstance();
        new Thread(this, name).start();
    }

    public void run(){
        char character = 'A';

        for(; character < 'Z'; character ++){
            buf.put(character);
            System.out.println("Producer " + Thread.currentThread().getName() + " puts " + character);
        }

        Consumer.done = true;
    }
}
public class Buffer {

    private static Buffer instance = null;
    private boolean full = false;
    private boolean empty = true;

    private char[] arr;
    private int i;

    private Buffer(){
        arr = new char[26];
        i = 0;
    }

    public static synchronized Buffer getInstance(){
        if(instance != null){
            instance = new Buffer();
        }
        return instance;
    }

    public synchronized void put(char c){
        while(full){
            try{
                wait();
            }catch(Exception e){}
        }

        arr[i++] = c;
        empty = false;
        if(i == 25){
            full = true;
            notifyAll();
        }else{
            full = false;
        }
    }

    public synchronized char get(){
        while(empty){
            try{
                wait();
            }catch(Exception e){}
        }

        if(--i == 0){
            empty = true;
        }else{
            notifyAll();
        }
        full = false;
        return arr[i];
    }

}

public class Consumer implements Runnable{

    private Buffer buf = null;
    public static boolean done = false;

    public Consumer(String name){
        buf = Buffer.getInstance();
        new Thread(this, name).start();
    }

    public void run(){      
        while(!done){
            System.out.println("Producer " + Thread.currentThread().getName() + " gets " + buf.get());
        }
    }
}



Exception in thread "Consumer2" Exception in thread "Consumer3" Exception in thread "Consumer1" Exception in thread "Producer1" java.lang.NullPointerException
    at Producer_consumer.Consumer.run(Consumer.java:15)
    at java.lang.Thread.run(Thread.java:745)
java.lang.NullPointerException
    at Producer_consumer.Consumer.run(Consumer.java:15)
    at java.lang.Thread.run(Thread.java:745)
java.lang.NullPointerException
    at Producer_consumer.Producer.run(Producer.java:16)
    at java.lang.Thread.run(Thread.java:745)
java.lang.NullPointerException
    at Producer_consumer.Consumer.run(Consumer.java:15)
    at java.lang.Thread.run(Thread.java:745)

最佳答案

你的 Buffer::getInstance 方法有 null 检查错误的方式,将其更改为

public static synchronized Buffer getInstance(){
    if(instance == null){
        instance = new Buffer();
    }
    return instance;
}

关于java - 需要帮助找出 Java 中的基本多线程代码有什么问题(多个生产者 - 一个消费者),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30158553/

相关文章:

python - 限制一次运行的最大线程数的正确方法?

java - 如果 MaximumPoolSize 小于 corePoolSize 该怎么办? Java 6 中可能存在错误吗?

c# - 在一种方法中锁定某个对象是否也会使其在其他方法中锁定?

java - 如何生成电话簿的可打印输出

java - 如何覆盖 google.Truth 中测试的默认失败消息?

java - libgdx - 按下后退按钮时舞台被禁用

创建多个内核线程——不使用 pthread

java - how = Selenium 中的 How.ID

java - 使用 DatagramPacket 欺骗源 IP/端口

java - ServerSocket 问题停止线程