这个问题与Java的最新版本有关。
30个生产者线程将字符串推送到抽象队列。一个写者线程从相同的队列中弹出并将字符串写入驻留在5400 rpm HDD RAID阵列上的文件中。数据以大约111 MBps的速率推送,以大约80MBps的速率弹出/写入。该程序存在5600秒,足够让大约176 GB的数据在队列中积累。另一方面,我限制使用总共64GB的主内存。
我的问题是:我应该使用哪种类型的队列?
到目前为止我尝试了以下方法。
1)ArrayBlockingQueue。有界队列的问题是,无论数组的初始大小如何,一旦填满就会出现存活问题。实际上,在程序启动几秒钟后,top报告只有单个活动线程。分析表明,平均而言,生产者线程大部分时间都在等待队列释放。这不管我是否使用公平访问策略(构造函数中的第二个参数设置为true)。
2)ConcurrentLinkedQueue。就活力而言,这个无界队列表现更好。直到我耗尽64GB的内存,大约七百秒后,所有三十个生产者线程都是活跃的。然而,在超过限制之后,情况变得非常缓慢。我推测这是由于分页问题造成的,尽管我没有进行任何实验来证明这一点。
我预见到了两种解决方法。
1)购买固态硬盘。希望I/O速率的增加会有所帮助。
2)在写入文件之前压缩输出流。
是否有其他选择?我在上述队列构建/使用方式上漏掉了什么?是否有更聪明的使用它们的方法?Java并发实践书中提出了许多饱和策略(第8.3.3节),以防有界队列填满得比可以用尽的速度快,但不幸的是,在我的情况下,没有一个(中断,调用方运行和两个丢弃策略)适用。
30个生产者线程将字符串推送到抽象队列。一个写者线程从相同的队列中弹出并将字符串写入驻留在5400 rpm HDD RAID阵列上的文件中。数据以大约111 MBps的速率推送,以大约80MBps的速率弹出/写入。该程序存在5600秒,足够让大约176 GB的数据在队列中积累。另一方面,我限制使用总共64GB的主内存。
我的问题是:我应该使用哪种类型的队列?
到目前为止我尝试了以下方法。
1)ArrayBlockingQueue。有界队列的问题是,无论数组的初始大小如何,一旦填满就会出现存活问题。实际上,在程序启动几秒钟后,top报告只有单个活动线程。分析表明,平均而言,生产者线程大部分时间都在等待队列释放。这不管我是否使用公平访问策略(构造函数中的第二个参数设置为true)。
2)ConcurrentLinkedQueue。就活力而言,这个无界队列表现更好。直到我耗尽64GB的内存,大约七百秒后,所有三十个生产者线程都是活跃的。然而,在超过限制之后,情况变得非常缓慢。我推测这是由于分页问题造成的,尽管我没有进行任何实验来证明这一点。
我预见到了两种解决方法。
1)购买固态硬盘。希望I/O速率的增加会有所帮助。
2)在写入文件之前压缩输出流。
是否有其他选择?我在上述队列构建/使用方式上漏掉了什么?是否有更聪明的使用它们的方法?Java并发实践书中提出了许多饱和策略(第8.3.3节),以防有界队列填满得比可以用尽的速度快,但不幸的是,在我的情况下,没有一个(中断,调用方运行和两个丢弃策略)适用。