Trying to speed up my image processing using Java OpenCV, I tried to use a parallel stream to consume a queue of OpenCV `<Mat>`. If I time the algorithm and count what is left on the queue, I get incoherent results when processing the stream in parallel, but sequential computing results are correct. Since I used a `ConcurrentLinkedQueue()`, I thought I was all good with thread safety and asynchronicity, but apparently not. Would anyone know how to circumvent this problem?

Remarks: 

* elements are still being put on the queue during its consumption
* I am running a 4 real (8 virtual) core processor

Results with a sequential stream:
---------------------------------

> 
> frame collection start size (=production): 1455
> 
> 
> frame collection end size (=production - consumption): 1360
> 
> 
> resulting list size after algorithm run (=consumption): 100
> 
> 
> algorithm: 6956 ms
> 
> 
> 

Results with a parallel stream:
-------------------------------

> 
> frame collection start size (=production): 1455
> 
> 
> frame collection end size (=production - consumption): 440
> 
> 
> resulting list size after algorithm run (=consumption): 100
> 
> 
> algorithm: 9242 ms
> 
> 
> 

My code:
--------

```
public class OvusculeTestConcurrent {

    public final static ConcurrentLinkedQueue<Mat> frameCollection = new ConcurrentLinkedQueue<Mat>();

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        final String path = "C:\\Users\\Raoul\\workspace\\aorta2\\ressource\\artery_src_for_dual.avi";
        long startAlgoTime = System.nanoTime();

        // Constitute a frame collection in async mode
        Capture cap = new Capture(path, frameCollection);
        new Thread(cap).start();
        Thread.sleep(3000); //leaves time to accumulate frames
        System.out.println("frame collection start size (=production): "+frameCollection.size());

        //Consumes the current queue in parallel/sequential
        List<ImagePlus> lm = Stream.generate(() -> {
                return frameCollection.poll();
            })
            .parallel() // comment to disable parallel computing
            .limit(100L)
            .map(img -> utils.PrepareImage(img,
                                    new Point(300, 250),
                                    new Point(450, 250),
                                    new Point(400, 400),
                                    0.25))
            .collect(Collectors.toList());

        //timing & printing the results
        long endAlgoTime = System.nanoTime();
        long algoDuration = (endAlgoTime - startAlgoTime)/1_000_000;  //divide by 1_000_000 to get milliseconds.
        System.out.println("frame collection end size (=production - consumption): "+frameCollection.size());
        System.out.println("resulting list size after algorithm run (=consumption): "+lm.size());
        System.out.println("algorithm: "+algoDuration+" ms");
        System.exit(0);
    }

}

```