Java 将一组对象从一个线程传递到另一个线程的最快数据存储是什么?
我有两个线程,一个读取流并从其内容生成数据对象 然后我必须将它们传递到第二个线程,将它们写入数据库 我想将这两个任务分开(这就是为什么我使用两个线程),因为流和数据库的I/O性能不同。在某些情况下,流速度很快,有时,db会有一些延迟 所以我想在它们之间放置一些(非常简单的!)数据存储 我的第一个想法是一个FILO解决方案,必须是线程安全的,并且应该是快速的(没有花哨的东西,只是放和拉)。顺序无关紧要。在某些时候,存储器中可能会有大约100000个条目(在使用db进行大约1秒的ping之后就是这种情况)Java 将一组对象从一个线程传递到另一个线程的最快数据存储是什么?,java,performance,storage,Java,Performance,Storage,我有两个线程,一个读取流并从其内容生成数据对象 然后我必须将它们传递到第二个线程,将它们写入数据库 我想将这两个任务分开(这就是为什么我使用两个线程),因为流和数据库的I/O性能不同。在某些情况下,流速度很快,有时,db会有一些延迟 所以我想在它们之间放置一些(非常简单的!)数据存储 我的第一个想法是一个FILO解决方案,必须是线程安全的,并且应该是快速的(没有花哨的东西,只是放和拉)。顺序无关紧要。在某些时候,存储器中可能会有大约100000个条目(在使用db进行大约1秒的ping之后就是这种
每个对象都有一个小的足迹,这正是生产者-消费者模式。看一看它的设计和实现 以下是我的示例代码:
公共类生成器实现可运行{
私有阻塞队列;
公共生产者(封锁队列){
this.queue=队列;
}
@凌驾
公开募捐{
//生产1000种产品
对于(int i=0;i<1000;i++){
queue.put(新产品());
System.out.println(“生产产品”);
}
}
}
公共类使用者实现可运行{
私有阻塞队列;
公共消费者(封锁队列){
this.queue=队列;
}
@凌驾
公开募捐{
while(true){
Product=queue.take();
系统输出打印项次(“消费品”);
}
}
}
这是呼叫代码:
BlockingQueue=new ArrayBlockingQueue(50);
生产者=新生产者(队列);
新线程(producer.start();
消费者=新消费者(队列);
新线程(consumer.start();
不要在线程之间复制对象。在线程之间传递指向对象的指针。并尝试在内存中保持对象的顺序。这样,当在线程之间传递一批对象时,CPU只需在CPU之间重新映射几个内存页
在大于操作系统内存页大小的线程之间批量传递对象
因此,为了获得理想的性能,您希望生产者使用一组内存页,消费者使用另一组内存页。CPU将确保一个核心使用的页面映射到该核心上的本地存储,其他页面映射到另一个核心上
如果不这样做,那么内存页在内核之间来回乒乓
如果你复制,那么它是相同的。当writer线程写入一个页面,而reader线程读取同一页面时,CPU将花费时间确保两个内核看到相同的数据
所以我会让读者读一堆东西,比如说价值16k的东西,而不是提供给消费者线程。填充完这些页面后,将它们释放到处理器线程,并分配另一个16k数据块以开始填充更多对象
public class Producer implements Runnable {
private BlockingQueue queue;
public Producer(BlockingQueue queue) {
this.queue = queue;
}
@Override
public void run() {
//Produce 1000 products
for (int i = 0; i < 1000; i++) {
queue.put(new Product());
System.out.println("PRODUCED PRODUCT");
}
}
}
public class Consumer implements Runnable {
private BlockingQueue queue;
public Consumer(BlockingQueue queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
Product product = queue.take();
System.out.println("CONSUMED PRODUCT");
}
}
}
And here is the calling code:
BlockingQueue queue = new ArrayBlockingQueue(50);
Producer producer = new Producer(queue);
new Thread(producer).start();
Consumer consumer = new Consumer(queue);
new Thread(consumer).start();