Reputation: 1331
I have a BlockingQueue which is being populated by a thread with put(). But I am confused on how to do take() for the BlockingQueue. Currently I implemented it this way:
String link;
try {
while(!(link = links.take()).isEmpty()) {
System.out.println(link);
}
} catch(InterruptedException ex) {
ex.printStackTrace();
}
Is that right? How is it possible to loop the queue and assign the string variable if not within the conditional statement?
Upvotes: 4
Views: 4711
Reputation: 9443
If I have understood correctly, you have asked for a way to take
outside of the condition? Well, it's not that hard:
while (!links.isEmpty()) {
try {
String link = links.take();
// Do stuff.
} catch (InterruptedException e) {
// Exception handling.
}
}
Your current condition !(link = links.take()).isEmpty()
checks if the return value—a string—is empty (length equals 0), not the queue.
Anyhow, please bear in mind that the code above is not atomic, so there's no guarantee that nothing else happens between links.isEmpty()
and links.take()
.
EDIT: You can handle race conditions during the startup with a flag:
BlockingQueue<Integer> numbers = new ArrayBlockingQueue<>(10);
AtomicBoolean flag = new AtomicBoolean(true);
// Producer.
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
numbers.put(i);
} catch (InterruptedException e) { /* NOP */ }
}
flag.set(false);
}).start();
// Consumer.
while (flag.get() || !numbers.isEmpty()) {
try {
System.out.println(numbers.take());
} catch (InterruptedException e) { /* NOP */ }
}
The AtomicBoolean
is not necessary here, but it might become handy if you have multiple producers and/or consumers. It's also part of java.util.concurrent
which you definitely should checkout.
Upvotes: 2
Reputation: 9492
My understanding is that you are asking on how to terminate a BlockingQueue in a good way. There are two scenarios I can think of. In any case you have a Message producer A and message consumer B.
Upvotes: 0