This question is related with one of my earlier questions..
Previous Post
In there the blocking nature is mentioned as an advantage.
I tried to develop some simple code to demonstrate the blocking nature but I got stuck. I just tried to make a BlockingQueue
of size 4 and tried to add 5 elements and ended up with a java.lang.IllegalStateException
. Can someone show me a code example for blocking nature of BlockingQueue
?
public static void main(String[] args) {
BlockingQueue<String> bq = new LinkedBlockingQueue<String>(4);
try {
bq.offer("A");
bq.offer("B");
bq.offer("C");
bq.offer("D");
bq.offer("E");
System.out.println("1 = " + bq.take());
System.out.println("2 = " + bq.take());
System.out.println("3 = " + bq.take());
System.out.println("4 = " + bq.take());
System.out.println("5 = " + bq.take());
System.out.println("6 = " + bq.take());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
I used this code segment. In this case I am trying to put 5 elements to a queue with size 4. In this case 4 elements (A,B,C,D) should be added to queue. Then I am calling take()
method while printing. Shouldn't "E" be inserted automatically to the queue when I call System.out.println("1 = " + bq.take());
? Because it gets one free slot?
Were you adding with add
, offer
, or put
? I assume you were using add
, since it is the only one that can throw an IllegalStateException
; but if you read the table, you'll see that if you want blocking semantics, you should be using put
(and take
to remove).
Edit: There are a couple of problems with your example.
First I'll answer the question "Why doesn't E get inserted when I call take()
the first time?" The answer is that by the time you call take()
, you have already tried and failed to insert E. There is then nothing to insert once the space has been freed.
Now if you changed offer()
to put()
, put("E")
will never return. Why? Because it's waiting for some other thread to remove an element from the queue. Remember, BlockingQueues
are designed for multiple threads to access. Blocking is useless (actually worse than useless) if you have a single-threaded application.
Here is an improved example:
public static void main(String[] args) {
final BlockingQueue<String> bq = new LinkedBlockingQueue<String>(4);
Runnable producer = new Runnable() {
public void run() {
try {
bq.put("A");
bq.put("B");
bq.put("C");
bq.put("D");
bq.put("E");
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
};
Runnable consumer = new Runnable() {
public void run() {
try {
System.out.println("1 = " + bq.take());
System.out.println("2 = " + bq.take());
System.out.println("3 = " + bq.take());
System.out.println("4 = " + bq.take());
System.out.println("5 = " + bq.take());
System.out.println("6 = " + bq.take());
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
};
new Thread(producer).start();
new Thread(consumer).start();
}
Now the put("E")
call will actually succeed, since it can now wait until the consumer thread removes "A" from the queue. The last take()
will still block infinitely, since there is no sixth element to remove.
mmyers beat me to it :P (+1)
that should be what you need, good luck!
NOTE: put() will fail in your example because put() will block until space is available. Since space is never available, the program never continues execution.
==== old answer======
a BlockingQueue is an interface, you'll have to use one of the implementating classes.
The "Blocking Nature" simply states that you can request something from your queue, and if it is empty, the thread it is in will block (wait) until something gets added to the queue and then continue processing.
ArrayBlockingQueue
DelayQueue
LinkedBlockingQueue
PriorityBlockingQueue
SynchronousQueue
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html
//your main collection
LinkedBlockingQueue<Integer> lbq = new LinkedBlockingQueue<Integer>();
//Add your values
lbq.put(100);
lbq.put(200);
//take() will actually remove the first value from the collection,
//or block if no value exists yet.
//you will either have to interrupt the blocking,
//or insert something into the queue for the program execution to continue
int currVal = 0;
try {
currVal = lbq.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With