4

I've written program solving bounded producer & consumer problem. While constructing ArrayBlockingQueue I defined capacity 100. I'm using methods take and put inside threads. And I've noticed that sometimes I see put 102 times with any take's between them. Why does it happen?

Producer run method:

public void run() {
    Object e = new Object();
    while(true) {
        try {
            queue.put(e);
        } catch (InterruptedException w) {
                System.out.println("Oj, nie wyszlo, nie bij");
        }
        System.out.println("Element added");

    }
}

Consumer run method:

public void run() {
    while(true) {
        try {
            queue.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Element removed");
    }
}

Part of uniq -c on file with output:

102 Element removed
102 Element added
102 Element removed
102 Element added
102 Element removed
102 Element added
102 Element removed
102 Element added
102 Element removed
102 Element added
102 Element removed
102 Element added
  2 Element removed
  2 Element added
102 Element removed
102 Element added
Gray
  • 115,027
  • 24
  • 293
  • 354
Wojciech Reszelewski
  • 2,656
  • 2
  • 18
  • 27

1 Answers1

5

I defined capacity 100. I'm using methods take and put inside threads. And I've noticed that sometimes I see put 102 times with any take's between them. Why does it happen?

This is most likely a byproduct of race conditions in your output instead of implying that the blocking queue ever has more than 100 entries in the queue. A thread might remove something from the queue after an element is put into the queue but displays the "removed" message before the putter can display the "added" message -- and vice versa. There is no locking between the queue calls and the System.out.println(...) so the order is not guaranteed.

If there is any question, print out queue.size() to see if it ever exceeds 100. The ArrayBlockingQueue will never show you that.

Gray
  • 115,027
  • 24
  • 293
  • 354
  • I created ArrayBlockingQueue with capacity = 1 and was able to add any number of objects to the queue. – Valeriy K. Apr 01 '19 at 12:07
  • 1
    Uh. Ok. Hi @ValeriyK. How are you? What `BlockingQueue` method did you call? If it was `queue.add(...)` then the 2nd call threw a "queue if full" exception and I bet you had a `catch(Exception)` which absorbed and dropped it. If it was `queue.put(...)` then it should hang on the 2nd call until someone takes from the queue. In the future, please provide more information and some niceties. – Gray Apr 01 '19 at 20:37
  • Hi. Yes, you are right. It was several sequential queue.put(..) methods, just for test. I thought they work one after other. But when I added logs I saw that queue size always equals 1. Each put method call waits until another method takes an element from the queue. – Valeriy K. Apr 02 '19 at 07:53