多线程Java

6
在我的程序中,我有一个类似于以下方法的方法:
for (int x=0; x<numberofimagesinmyfolder; x++){
    for(int y=0; y<numberofimagesinmyfolder; y++){
        compare(imagex,imagey);
        if(match==true){
            System.out.println("image x matches image y");
        }
    }
}

基本上,我有一组图片文件夹,并且我要比较其中所有的图片组合……先将第一张图片与所有图片进行比较,然后再将第二张图片进行比较……以此类推。我的问题在于,搜索匹配的图片需要很长时间。我正在尝试多线程处理这个过程。有没有人有任何想法如何做到这一点?


你是按照某些参数进行比较,还是两张图片必须完全相同? - Autocrab
2个回答

8

不要每次比较图像,而是对图像进行哈希处理,保存哈希值,然后比较每个消息对的哈希值。由于哈希值远比图像小,可以将更多哈希值放入内存和缓存中,这应该显着加速比较。

可能还有更好的方法来搜索相等性,但其中一个选项是将所有哈希值都放入数组中,然后按哈希值对它们进行排序。然后遍历列表,查找相邻的条目是否相等。这应该是O(n*log(n)),而不是像当前版本一样的O(n^2)


根据使用的哈希算法,您可能需要实际比较相等性(使用SHA-256或类似算法时,这种机会将是微不足道的)。此外,只需使用HashMap<Hash,List<String>>使其成为O(n)。对于大多数情况,除了将IO与哈希计算分离之外,进一步进行多线程处理可能甚至都不值得。 - Voo

3
  1. 内循环应该从y=x+1开始,以利用对称性。
  2. 先将所有图像加载到内存中。不要从磁盘上进行所有的比较。
  3. 使用Java ExecutorService(基本上是线程池)。为所有索引组合排队任务。让线程从任务队列中获取索引组合并执行比较。

以下是一些通用代码来进行多线程处理:

public static class CompareTask implements Runnable {
    CountDownLatch completion;
    Object imgA;
    Object imgB;

    public CompareTask(CountDownLatch completion, Object imgA, Object imgB) {
        this.completion = completion;
        this.imgA = imgA;
        this.imgB = imgB;
    }

    @Override
    public void run() {
        // TODO: Do computation...

        try {
            System.out.println("Thread simulating task start.");
            Thread.sleep(500);
            System.out.println("Thread simulating task done.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        completion.countDown();
    }
}

public static void main(String[] args) throws Exception {
    Object[] images = new Object[10];

    ExecutorService es = Executors.newFixedThreadPool(5);

    CountDownLatch completion = new CountDownLatch(images.length * (images.length - 1) / 2);

    for (int i = 0; i < images.length; i++) {
        for (int j = i + 1; j < images.length; j++) {
            es.submit(new CompareTask(completion, images[i], images[j]));
        }
    }

    System.out.println("Submitted tasks. Waiting...");
    completion.await();
    System.out.println("Done");

    es.shutdown();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接