2012-02-17 15 views
0

假设我有一个需要调整一些图像文件大小的多线程应用程序。我不希望多个线程能够同时调整相同的图像并覆盖其他人的结果并损坏文件,但为了最大化并发性,我希望多个线程能够同时调整不同图像的大小。在Java中调整图像文件大小时最大化并发性

线程获取特定映像上的锁而不是简单地同步整个代码块的最佳方法是什么?

+0

它很模糊您在此处的“图像”的含义。文件?堆中的图像实例? – Durandal 2012-02-17 16:19:47

+0

我猜他的意思是堆 – Adrian 2012-02-17 16:23:35

+0

我的意思是文件,最终我不希望线程A在A完成并损坏文件之前覆盖线程B的结果。我会修改这个问题。 – 3urdoch 2012-02-17 16:31:26

回答

2
  • 使用固定线程ExecutorService并有一个线程将所有图像提交到要处理的服务中。只要你不提交相同的图像两次,你不会有问题。

  • 你也可以有一个线程,为其他线程使用“todo”BlockingQueue。那么你有一个线程可以控制线程工作的图像,所以不需要锁。

  • 另一种方法是使用ConcurrentHashMap,并让每个线程putIfAbsent然后只有在它工作时才使用图像。

    if (concurrentMap.putIfAbsent(imagePath, null) == null) { 
        // do the processing 
        // either remove it from map when done or leave it to stop future processing 
    } 
    // I guess loop around and look at the next image 
    
+0

我不会控制请求图像调整大小的线程,我只知道会有很多这样的线程。所以我认为唯一的方法就是使用ConcorrentHashMap技术。 这已经是我的想法,所以你已经验证了我。 – 3urdoch 2012-02-17 16:52:28

+0

如果你坚持要多线程,我会做1或3; 2不可扩展。可以说1也不好。 – Adrian 2012-02-17 18:45:22

+0

为什么#2无法扩展@Adrian?这大概是“ExecutorService”正在做的事情。 – Gray 2012-02-17 18:48:50

-1
  • 如果图像是在内存中,你有1个CPU,使用1线程只。由于没有阻塞的等待或其他延迟,因此线程之间的上下文切换没有任何意义。
  • 如果您有n个CPU,则可以使用1个线程/ CPU。
  • 如果您的映像位于不同的驱动器上,比如RAID,您可以使用1个线程/驱动器并行加载它们,并使用1个线程来调整大小。您可以使用生产者消费者范例。

编辑:刚才看到的回复我的评论
- 因为图像是磁盘上的文件使用1线从磁盘中读取图像1线程处理。假设调整图像大小不会花费比HDD延迟更长的时间来查找文件并加载它们。