1

Behind the code

So, my understanding is that the put() method suspends the Producer if the queue(which is shared here) is full, when this happens Consumer will be working and remove items from the queue(shared), to make more room for the Producer. The Producer resumes operation if put() has found out the queue is no longer full. This sequence continues until the Producer finishes. Consumer is not done if there still item left in queue. The sum of all Consumed item should equal to that of the amount Producer produced.

Question

So, I'm getting error message like this.

Exception in thread "pool-1-thread-2" java.lang.NullPointerException
at Consumer.run(Consumer.java:33)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

I have read about NullPointerException and what i am guessing is that queue is set as null, and it is pointing at nothing, so I added the code to check for a null in consumer class while(queue.poll() != null) . It still solves nothing. This was my best guess for last 7 hours.. Can anybody help me with this?

This is Main

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class Main {
    public static void main(String args[]){

    LinkedBlockingQueue<String> shared = new LinkedBlockingQueue<String>(1000);

    ExecutorService executor = Executors.newCachedThreadPool();
    executor.execute(new Producer(shared));
    executor.execute(new Consumer(shared,"customer1"));
    executor.execute(new Consumer(shared,"customer2"));
    executor.shutdown();

    }
}

Consumer class

import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class Consumer implements Runnable{
    private LinkedBlockingQueue<String> queue;
    private String _name;
    private Random random = new Random();
    private int wait;
    private String cheksmax;

    public Consumer(LinkedBlockingQueue<String> shared, String name){
        queue = shared;
        _name = name;
        wait = random.nextInt(50);
    }

    @Override
    public void run() {
        int remainder = 0;

        try {
            cheksmax = queue.take().toString();
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        // TODO Auto-generated method stub
        while(queue.poll() != null){
            // !queue.isEmpty()
            // produce.isRunning()
            try {
                String secondQueue = queue.take().toString();
                    if(secondQueue.compareTo(cheksmax)>0){
                        cheksmax = secondQueue;
                        remainder++;
                    }
                    if(remainder % 100 == 0){
                        System.out.println(_name + ": " + remainder);
                    }
                    Thread.sleep(wait);

                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }       
        System.out.println(_name + " consuming Done!");
        }
    }

Producer class

import java.util.Random;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class Producer implements Runnable{
    private String uuid;
    private LinkedBlockingQueue<String> queue;
    private boolean running;
    private int wait;
    private Random random = new Random();

    //constructor
    public Producer(LinkedBlockingQueue<String> shared){
        queue = shared;
        wait = random.nextInt(50);
        running = true;
    }

    public boolean isRunning(){
        return running;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        int remainder = 0;

        for(int i=0; i<5000; i++){
            try {
                uuid = UUID.randomUUID().toString();
                queue.put(uuid);
                remainder++;

                if(remainder % 100 == 0){
                    System.out.println("produced: " + remainder);
                }
                Thread.sleep(wait);

            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
        System.out.println("producing Done!");
    }

}

HappyThanksgiving!

  • 4
    poll: "Retrieves **and removes** the head of this queue, or returns null if this queue is empty." Cited from https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/LinkedBlockingQueue.html#poll-- => You are throwing away entries! – Fildor Nov 25 '16 at 08:36
  • 2
    It would have helped if you told us which line is line 33. – Mike Nakis Nov 25 '16 at 08:37
  • Also, checking the queue for empty to end the consumer could lead to premature exit. What if consumers are faster than producer? – Fildor Nov 25 '16 at 08:41
  • Delete the call to `poll` and use only `take`. Insert a special "producer done" element to terminate the consumer. – Marko Topolnik Nov 25 '16 at 08:45
  • 2
    while(!queue.isEmpty() || produce.isRunning()) @MikeNakis – Kyunam Park Nov 25 '16 at 08:57
  • @Fildor Yes,, it happens with while(!queue.isEmpty()). Gives me consumer done! before producing anything. – Kyunam Park Nov 25 '16 at 09:05
  • btw: "queue.take().toString()" - toString is not needed. It is already a string that you'll get. – Fildor Nov 25 '16 at 09:05
  • NPE could be from cheksmax. In case of Interruption it may be null. InterruptedException is caught, so code will move on and then [compareTo](https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html#compareTo-T-) will throw NPE -> docs: "Throws: NullPointerException - if the specified object is null" – Fildor Nov 25 '16 at 09:10
  • @Fildor hmm, ok so I put cheksmax = queue.take(); right above String secondQueue = queue.take();. so cheksmax is now in while loop. Good news is that is now giving me no NPE, and also prints out like customer: 100. But, now producer never stop producing. it just ignoring limitation. and customer1: 100 prints out multiple times. – Kyunam Park Nov 25 '16 at 09:32
  • @Fildor I'm using while(_produce.isRunning() || !queue.isEmpty()) loop, since you mentioned while(poll()) is throwing away all the items. – Kyunam Park Nov 25 '16 at 09:34
  • 1
    The exception message gave you the **exact** line number where the NPE took place. Obviously it was at ` cheksmax = queue.take().toString()` ... there is **no** check on the queue before you call take(), so that call is supposed to return null for empty queues! In other words: A) just read that exception message carefully B) study the javadoc of the methods you are using. C) and when you are quoting your exception message, than tell us which line matches that line 33! – GhostCat Nov 25 '16 at 09:40
  • @GhostCat `java.util.concurrent.BlockingQueue#take` is a blocking operation, on an empty queue it will block, rather than return `null`. It *can* return `null` if there's a null value on the queue. But the OP's code doesn't seem to put `null`s on the queue. – bowmore Nov 25 '16 at 12:09
  • @bowmore Does that really matter in the end? The point is: he knows which lines encounters the null. So he has to debug from there. If he is not pushing a null into the queue, the only explanation is that the queue object itself must be null. That is the point of the "dupped" answer: there are good, proven strategies to debug and fix NPEs. – GhostCat Nov 25 '16 at 12:13
  • @GhostCat it matters in the sense that take doesn't return ´null´ on empty queues, and so the problem is definitely not that he's forgotten to properly handle that case. At any rate, I don't get a NPE when running this code a few times. – bowmore Nov 25 '16 at 12:21
  • @Kyunam Park were you able to fix this problem? you may also check this http://stackoverflow.com/q/40029696/5086633 (A similar problem for Producer consumer I had sometime back) – yeppe Nov 28 '16 at 11:42

0 Answers0