如何返回线程找到的信息

时间:2012-07-13 16:31:13

标签: java multithreading

我遇到以下情况:

  • 大约10个抓取网络图片的主题
  • 所有找到的图像必须以某种方式返回到其他10个线程(用于分析)

如上所述,我想用10 其他线程同时处理图片

目前我有一个自己列表的 Singleton 实现:

public class ImageList extends Observable implements Iterable<Image> {
    private final BlockingQueue<Image> images = new LinkedBlockingQueue<Image>();

    private static class InstanceHolder {
        public static ImageList instance = new ImageList();
    }

    public static ImageList getInstance() {
        return InstanceHolder.instance;
    }

    private ImageList() {

    }

    public synchronized void execute(Image job) throws InterruptedException {
        images.put(job);

        new Thread(job).start();

        System.out.println("notify observers");
        this.setChanged();
        this.notifyObservers();

        System.out.println(this.countObservers());
    }

    @Override
    public Iterator<Image> iterator() {
        return images.iterator();
    }
}

一旦找到图像,我就会执行ImageList.execute(image),但我不喜欢这个解决方案,因为并行进程有没有上限(它可能会变成数千个)。

我的另一个想法是:

  • 附加列表 imagesFound传递给我的所有抓取工具,让他们将所有图片添加到该列表中
  • 在Main类中启动5个线程,不断检查imagesFound中的新元素并处理它们

但是,我也不喜欢这个解决方案,因为线程传递一个不是真的需要的数组(但只是用来传回找到的数据)似乎错了对我来说。如果我想在网站上搜索20种不同的信息,它可能会成为20个不同的列表。

那么,你通常如何实现从线程返回数据(在我的情况下:特别是如果这些数据本身应由其他线程处理)。

1 个答案:

答案 0 :(得分:4)

也许是线程池?查看ExecutorService

  • 您可以设置工作线程数。
  • 它会自动封装一个线程安全的工作队列。

示例:

class Task implements Callable<Object> {

    private Image job;

    public Task(Image job) {
       this.job = job;
    }

    public Object call() {
        // crawl
        return result;
    }
}

...

// Initialize thread pool
ExecutorService exec = Executors.newFixedThreadPool(10);

// every time you get a new job
Future<Object> result = exec.submit(new Task(job));

// when you want to collect the result
Object obj = result.get();