1

I get tons of meaningless (for me) exception when run this code. Not sure where I could make a mistake... Basically I want my producer to puts alpha chars in the buffer and consumers to get them from a buffer and print. I just started to learn multithreading and I have no idea what could be the potential problem in this code. I tried to implement in-class example. I really apologize if it is a dumb question...

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)
YohanRoth
  • 3,153
  • 4
  • 31
  • 58
  • And the consumer would be? – MadProgrammer May 11 '15 at 01:47
  • 1
    Well, your ctors for `Producer` and `Consumer` have `this` escapes, which is a no-no. Basically your class isn't fully constructed yet (because you're still inside the constructor) but you publish a `this` pointer to an external class and expect it to use your class. May not be root cause but generally indicative of sloppy code. – markspace May 11 '15 at 01:54
  • Which line is line 15 of Consumer.java? – Kevin Krumwiede May 11 '15 at 02:03
  • @KevinKrumwiede 15 is just closed braces.. 14 is System.out.println("Producer " + Thread.currentThread().getName() + " gets " + buf.get()); – YohanRoth May 11 '15 at 02:04
  • @markspace not a reason of the bug. Not sure why it does not work, this is how out professor does it and it worked before. But I agree that it might be.. "not good to do". Possibly. – YohanRoth May 11 '15 at 02:05
  • It's impossible to get a NPE on a line that is just close braces. Are you sure you recompiled your code after the most recent changes? – Kevin Krumwiede May 11 '15 at 02:06
  • @PTNPNX It is definitately not good to do. See [Effective Java](http://www.amazon.com/exec/obidos/ASIN/0321356683/ref=nosim/javapractices-20) by Joshua Bloch, and this [page on this-escape.](http://www.javapractices.com/topic/TopicAction.do?Id=252) It's bad news. Tell your professor to knock it off, or at least don't emulate his or her code. – markspace May 11 '15 at 02:09

1 Answers1

3

your Buffer::getInstance method has the null check the wrong way, change it to

public static synchronized Buffer getInstance(){
    if(instance == null){
        instance = new Buffer();
    }
    return instance;
}
muued
  • 1,666
  • 13
  • 25
  • This is epic fail haha I was killing myself over Thread theory and where did I do it front.. But I was wrong in Singleton creation.. jeez dumb mistake – YohanRoth May 11 '15 at 02:09