简体   繁体   English

多线程Java

[英]Multi Threading Java

In my program I essentially have a method similar to: 在我的程序中,我基本上有一个类似于的方法:

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");
        }
    }
}

So basically I have a folder of images and I compare all combinations of images...so compare image 1 against all images then image 2...and so on. 所以基本上我有一个图像文件夹,我比较所有图像组合...所以比较图像1与所有图像,然后图像2 ......等等。 My problem is when searching to see what images match, it takes a long time. 我的问题是在搜索什么图像匹配时,需要很长时间。 I am trying to multithread this process. 我试图多线程这个过程。 Does anyone have any idea of how to do this? 有没有人知道如何做到这一点?

Instead of comparing the images every time, hash the images, save the hash, and then compare the hashes of each pair of messages. 不是每次都比较图像,而是散列图像,保存散列,然后比较每对消息的散列。 Since a hash is far smaller you can fit more into memory and cache, which should significantly speed up comparisons. 由于哈希值要小得多,因此可以更多地放入内存和缓存中,这样可以显着加快比较速度。

There is probably a better way to do the search for equality as well, but one option would be to stick all the hashes into an array then sort them by hash value. 也许有一种更好的方法来搜索相等性,但一种选择是将所有哈希值粘贴到一个数组中,然后按哈希值对它们进行排序。 Then iterate over the list looking for adjacent entries that are equal. 然后迭代列表,查找相等的相邻条目。 This should be O(n*log(n)) instead of O(n^2) like your current version. 这应该是O(n*log(n))而不是O(n^2)就像您当前的版本一样。

  1. inner loop should start at y=x+1 to take advantage of symmetry. 内环应该从y = x + 1开始,以利用对称性。
  2. load all images into memory first. 首先将所有图像加载到内存中。 don't do all compares from disk. 不要从磁盘进行全部比较。
  3. Use a Java ExecutorService (basically a thread pool). 使用Java ExecutorService(基本上是一个线程池)。 Queue tasks for all index combinations. 所有索引组合的队列任务。 Let threads pull index combinations out of a task queue and execute comparisons. 让线程将索引组合从任务队列中拉出并执行比较。

Here is some general code to do the multi threading: 以下是执行多线程的一些通用代码:

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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM