Concurrent and Blocking Queue in Java

后端 未结 6 2058
一生所求
一生所求 2020-12-12 18:42

I have the classic problem of a thread pushing events to the incoming queue of a second thread. Only this time, I am very interested about performance. What I want to achiev

相关标签:
6条回答
  • 2020-12-12 18:47

    I think you can stick to java.util.concurrent.LinkedBlockingQueue regardless of your doubts. It is concurrent. Though, I have no idea about its performance. Probably, other implementation of BlockingQueue will suit you better. There's not too many of them, so make performance tests and measure.

    0 讨论(0)
  • 2020-12-12 18:47

    Here is a list of classes implementing BlockingQueue.

    I would recommend checking out SynchronousQueue.

    Like @Rorick mentioned in his comment, I believe all of those implementations are concurrent. I think your concerns with LinkedBlockingQueue may be out of place.

    0 讨论(0)
  • 2020-12-12 18:49

    I use the ArrayBlockingQueue whenever I need to pass data from one thread to another. Using the put and take methods (which will block if full/empty).

    0 讨论(0)
  • 2020-12-12 18:54

    Similar to this answer https://stackoverflow.com/a/1212515/1102730 but a bit different.. I ended up using an ExecutorService. You can instantiate one by using Executors.newSingleThreadExecutor(). I needed a concurrent queue for reading/writing BufferedImages to files, as well as atomicity with reads and writes. I only need a single thread because the file IO is orders of magnitude faster than the source, net IO. Also, I was more concerned about atomicity of actions and correctness than performance, but this approach can also be done with multiple threads in the pool to speed things up.

    To get an image (Try-Catch-Finally omitted):

    Future<BufferedImage> futureImage = executorService.submit(new Callable<BufferedImage>() {
        @Override
            public BufferedImage call() throws Exception {
                ImageInputStream is = new FileImageInputStream(file);
                return  ImageIO.read(is);
            }
        })
    
    image = futureImage.get();
    

    To save an image (Try-Catch-Finally omitted):

    Future<Boolean> futureWrite = executorService.submit(new Callable<Boolean>() {
        @Override
        public Boolean call() {
            FileOutputStream os = new FileOutputStream(file); 
            return ImageIO.write(image, getFileFormat(), os);  
        }
    });
    
    boolean wasWritten = futureWrite.get();
    

    It's important to note that you should flush and close your streams in a finally block. I don't know about how it performs compared to other solutions, but it is pretty versatile.

    0 讨论(0)
  • 2020-12-12 19:00

    You can try LinkedTransferQueue from jsr166: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166y/

    It fulfills your requirements and have less overhead for offer/poll operations. As I can see from the code, when the queue is not empty, it uses atomic operations for polling elements. And when the queue is empty, it spins for some time and park the thread if unsuccessful. I think it can help in your case.

    0 讨论(0)
  • 2020-12-12 19:10

    I would suggest you look at ThreadPoolExecutor newSingleThreadExecutor. It will handle keeping your tasks ordered for you, and if you submit Callables to your executor, you will be able to get the blocking behavior you are looking for as well.

    0 讨论(0)
提交回复
热议问题