使用另一个线程获取在一个线程中创建的数据

时间:2016-05-03 19:45:18

标签: java multithreading

我应该创建2个线程。一个从文件中读取数据并创建类Merchandise的对象。该文件本身包含10,000多行:

IdOfMerchandise  Weight

第一个线程创建Merchandise对象行,并为其写入每200个对象。我遇到的问题是,我需要第二个线程,与第一个线程同时工作,获取这些对象并总结总体重量,每增加100个报告。

如何在另一个线程中创建对象数据的同时使用该线程获取对象数据?使用HashMap的好主意是用2个变量存储新创建的类对象吗?

2 个答案:

答案 0 :(得分:1)

当您将数据从一个线程传递到另一个线程时,您需要一个thread-safe数据结构。正如您正确指出的那样,HashMap不是线程安全的。对于Java中的线程安全集合,请查看java.util.concurrent包。实现生产者 - 消费者模式的最简单方法之一是使用LinkedBlockingQueue

这是一个包含两个线程的完整示例,一个生成对象,另一个消耗并打印每100个对象:

AtomicBoolean finished = new AtomicBoolean(false);
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();

Thread thread1 = new Thread(() -> {
    for (int i = 0; i < 10000; i++) {
        String createdObject = Integer.toString(i);
        queue.offer(createdObject);
    }
    finished.set(true);
});

Thread thread2 = new Thread(() -> {
    int count = 0;
    while (!finished.get() || !queue.isEmpty()) {
        try {
            String object = queue.poll(100, TimeUnit.MILLISECONDS);
            if (count++ % 100 == 0) {
                System.out.println(object);
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
});

thread1.run(); thread2.run();
thread1.join(); thread2.join();

您可能会注意到一件事 - 除了生产的产品之外,线程还需要交换其他信息 - 当生产者完成时。同样,如果没有同步,您将无法安全地交换此信息。您可以使用示例中的AtomicBooleanvolatile field

答案 1 :(得分:0)

似乎是生产者 - 消费者问题。这个官方链接将帮助您理解和实施这一概念。

Guarded Blocks

基本思想是,除非生产者生产了东西,否则消费者不能消费。