并发和阻止队在Java
-
06-07-2019 - |
题
我已经典问题的一个螺纹推动事件进入队列中的第二线。只有这个时候,我非常感兴趣的有关性能。什么我想要实现的是:
- 我希望同时访问的队列,生产者推动,该接收机油炸.
- 在队列为空时,我想消费者块排队,等待生产者。
我第一个想法是使用一个 LinkedBlockingQueue
, 但我很快就意识到,它不是并行和业绩受到影响。另一方面,我现在使用一个 ConcurrentLinkedQueue
, 但我仍然支付的费用 wait()
/ notify()
在每个出版物。由于消费,在找到一个空队列,不会阻止,我要同步 wait()
上锁。在其他部分,生产者已经得到那个锁 notify()
在每一个出版物。总的结果是,我付钱的成本
sycnhronized (lock) {lock.notify()}
在每一个出版物,即使不需要的。
我的猜测是需要这里是一队,这既是阻止和并行。我想象一个 push()
操作的工作,作为在 ConcurrentLinkedQueue
, 与一个额外的 notify()
到目时推元是第一个在名单。这样的检查我考虑到已经存在的 ConcurrentLinkedQueue
, ,作为推动需要连接的下一个元素。因此,这将大大快于同步的每一个时间在外锁。
是这样的事情可/合理的吗?
解决方案
我认为你能坚持到 java.util.concurrent.LinkedBlockingQueue
不管你的疑虑。它是同时进行。虽然我不知道关于它的性能。也许,其他执行 BlockingQueue
会更适合你.有没有太多的人,所以性能测试和测量。
其他提示
类似这样的回答 https://stackoverflow.com/a/1212515/1102730 但一点不同..最后我用一个 ExecutorService
.你可以化一个通过使用 Executors.newSingleThreadExecutor()
.我需要一个并发的队列为读写BufferedImages的文件,以及原子性有读和写。我只需要一个线程,因为该文件IO大快于源,净IO.此外,我更关心原子性的行动和正确性比的性能,但这种做法还可以做多线程的游泳池来加快速度。
获得的图像(尝试追赶最后从略):
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();
保存有图像(尝试追赶最后从略):
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();
重要的是要注意,你应该冲闭上你的流在最后一块。我不知道它是如何执行其他解决方案相比,但是它是相当灵活。
我会建议你看看 ThreadPoolExecutor newSingleThreadExecutor.它将处理保持你的任务命令你,如果你提交 可调用类型 你的遗嘱执行人,你将能够得到阻止的行为你是在寻找。
你可以尝试LinkedTransferQueue从jsr166: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166y/
它满足了你的需求,并有较少的开销用于提供/调查行动。我可以看到从码,当时的队列并不是空的,它使用原子操作投票的要素。及时的队列是空的,它旋转了一段时间,公园的线程如果不成功的。我认为它可以帮助你的情况。
我用的是ArrayBlockingQueue每当我需要将数据从一个线程到另一个。使用投入并采取方法(这将框如果全面/空)。
这里是一个 列表类的实施 BlockingQueue
.
我会建议检查了 SynchronousQueue
.
像@罗瑞克在他的评论,我相信所有那些实现并发。我认为你担忧 LinkedBlockingQueue
可出来的地方。