我需要使用两个线程创建一个生产者 - 消费者的真实性。一种是从磁盘上的文件中读取文本对象,然后将对象插入FIFO中的队列,并且消费者线程正在从队列中读取以处理对象。但是我很困惑什么类使用? LinkedBlockingQueue还是PriorityBlockingQueue?甚至更好的东西?
目标&目的:
我正在尝试实时聚类推文,但我将csv文件中的推文存档而不使用Twitter Streaming API。所以我试图通过从文件中读取推文并将它们放入队列然后消费者开始从队列中读取来模拟流的效果。我真的有很大的csv文件,所以我更像是一个流媒体场景。因此,当我收到推文时,消费者会从队列中获取推文并实时聚类。
答案 0 :(得分:3)
PriorityBlockingQueue似乎没有意义,因为您只想按原始顺序处理邮件。
如果您真的想自己处理队列,可以使用有界LinkedBlockingQueue:
//example with a limit of 100,000 messages being in the queue at any one time
private static final BlockingQueue<Message> queue =
new LinkedBlockingQueue<> (100_000);
在你一直在做的制作人中:
Message msg = getMessage();
queue.put(msg); //blocks if the queue is full
并且在消费者中:
Message msg = queue.take(); //blocks until there is a message
Peter Lawrey的替代方案包括:
private static final ExecutorService executor = Executors.newFixedThreadPool(10);
在您的制片人中:
final Message msg = getMessage();
Runnable task = new Runnable() {
public void run() { process(msg); }
}
executor.submit(task);
自从您的制作人创建了它(任务)以来,没有任何comsumer。
注意:在线程池示例中,我使用了10个线程的大小,这是基于process
方法主要受CPU约束并且您有大约10个处理器的假设。在实践中:
Runtime.getRuntime().availableProcessors()
来获取处理器的数量,而不是带有编号的数字。答案 1 :(得分:1)
您可以使用LinkedBlockingQueue,但通常使用包装队列和线程池的ExecutorService更简单。您可以为每项工作提交任务。
PriorityBlockingQueue用于设置任务的优先级。
我会查看文档中的示例。
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html