I think mistakenly guys compared take() vs poll(), but I found that it is reasonable to compare take() vs poll(time, unit) as both provided by BlockingQueue and both are blocking tell queue not Empty "and in case or poll or time-out", OK lets start comparing, usually I'm using take() for BlockingQueue but I was facing issues about:
- handling interrupt inside loop.
- waiting till be interrupted from outside.
- how to stop looping on queue "using Kill-Bill or interrupt thread"
specially when work with Java 8 streams, then I got idea about I need to stop retrieving data from queue and close it in better way, so I thought to make waiting for sometime after that I can stop retrieve data then I found poll(time, unit) and it will fit for this idea check code below:
public static void main(String[] args) throws InterruptedException {
BlockingQueue<Integer> q = new LinkedBlockingQueue<Integer>();
ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(() -> {
IntStream.range(0, 1000).boxed().forEach(i -> {
try {
q.put(i);
} catch (InterruptedException e) {
currentThread().interrupt();
throw new RuntimeException(e);
}
});
});
....
// Take
Future fTake = executor.submit(() -> {
try {
while (!Thread.currentThread().isInterrupted()) {
System.out.println(q.take());
}
} catch (InterruptedException e) {
currentThread().interrupt();
throw new RuntimeException(e);
}
});
//to stop it I have to do below code "Expecting that execution will take 1 sec"
executor.shutdown();
sleep(1000);
fTake.cancel(true);
....
// poll there is no need to expect time till processing will be done
Future fPoll = executor.submit(() -> {
try {
Integer i;
while ((i = q.poll(100, TimeUnit.MILLISECONDS)) != null)
System.out.println(i);
} catch (InterruptedException e) {
currentThread().interrupt();
throw new RuntimeException(e);
}
});
executor.shutdown();
}
I think the poll code is more clean and there is no need to depend on interrupt and also no need to estimate execution time or make code to determined when to interrupt thread, what do you think?
Note 1: I'm sure that 2nd solution also have drawbacks like not getting data till time-out but I think you are going to know what is suitable time-out for your case.
Note 2: if use case requires waiting for ever and producer is low frequency provide data, I think take solution is better.