Java 多线程文件排序
我通过读取数据块(Arraylist)对大文件进行排序,使用Collections.sort自定义比较器对每个Arraylist进行排序,并将排序结果写入文件,然后对所有文件应用合并排序算法 我用一根线做这件事 如果我为每个Collections.sort()启动一个新线程,是否会提高性能 我的意思是:Java 多线程文件排序,java,multithreading,file,sorting,Java,Multithreading,File,Sorting,我通过读取数据块(Arraylist)对大文件进行排序,使用Collections.sort自定义比较器对每个Arraylist进行排序,并将排序结果写入文件,然后对所有文件应用合并排序算法 我用一根线做这件事 如果我为每个Collections.sort()启动一个新线程,是否会提高性能 我的意思是: 我从文件中读取到列表中,当列表已满时,我启动一个新线程,对列表进行排序并写入临时文件 同时,我继续从文件中读取,并在列表再次满时启动一个新线程 我还有一个问题: 什么更适合排序: 1) 我填充的
我从文件中读取到列表中,当列表已满时,我启动一个新线程,对列表进行排序并写入临时文件 同时,我继续从文件中读取,并在列表再次满时启动一个新线程 我还有一个问题: 什么更适合排序:
1) 我填充的Arraylist,当它已满时应用collections.sort()
2) 我填充的树映射,我不需要对它进行排序。(在我插入项目时进行排序) 注意:我使用Java1.5 更新: 这是我想要使用的代码,问题是我正在重用线程正在使用的datalines arraylist,而且我需要等待所有线程完成。 我怎么修理
int MAX_THREADS = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS);
List datalines = ArrayList();
try {
while (data != null) {
long currentblocksize = 0;
while ((currentblocksize <= blocksize) && (data = getNext()) != null) {
datalines.add(data);
currentblocksize += data.length();
}
executor.submit(new Runnable() {
public void run() {
Collections.sort(datalines,mycomparator);
vector.add(datalines);
}
});
int MAX_THREADS=Runtime.getRuntime().availableProcessors();
ExecutorService executor=Executors.newFixedThreadPool(最大线程数);
List datalines=ArrayList();
试一试{
while(数据!=null){
长currentblocksize=0;
而((currentblocksize使用线程是否会加快速度取决于磁盘I/O还是CPU速度。这取决于磁盘的速度(SSD比旋转硬盘快得多),以及比较函数的复杂程度。如果限制是磁盘I/O,那么添加线程或担心数据结构就没有意义了,因为这些都不会帮助您更快地从磁盘读取数据。如果限制是CPU速度,那么您应该首先运行探查器,以确保比较函数不会执行任何缓慢和愚蠢的操作。使用线程是否会加快速度取决于磁盘I/O还是CPU速度。这取决于磁盘的速度(SSD比旋转硬盘快得多),以及比较函数的复杂程度。如果限制是磁盘I/O,那么添加线程或担心数据结构就没有意义了,因为这些都不会帮助您更快地从磁盘读取数据。如果限制是CPU速度,那么您应该首先运行探查器,以确保比较函数不会执行任何缓慢和愚蠢的操作。第一个问题的答案是-是。如果实现合并排序的并行化版本,将获得性能提升。关于这方面的更多信息,请参阅Dobbs博士的文章:。第一个问题的答案是-是。如果实现合并排序的并行化版本,将获得性能提升。有关这方面的更多信息,请参阅本节Dobbs博士文章:。如果您的进程是CPU绑定的(我怀疑不是),您可以看到使用多线程的改进。如果您的进程是IO绑定的,您需要提高IO带宽和操作速度。如果您的进程是CPU绑定的(我怀疑不是)您可以看到使用多线程的改进。如果您的进程是IO绑定的,则需要提高IO带宽和操作速度。我建议您实施以下方案,称为场:
worker0
reader --> worker1 --> writer
...
workerN
因此,一个线程从文件中读取一个块,将其交给工作线程(最佳做法是让工作线程作为执行器服务
)对其进行排序,然后每个工作线程将其输出发送到写入线程以放入临时文件
编辑:好的,我已经查看了您的代码。若要解决共享的数据线
的问题,您可以为存储线程需要排序的当前数据线
数组的每个线程指定一个私有成员:
public class ThreadTask implements Runnable {
private List datalines = new ArrayList();
public ThreadTask(List datalines) {
this.datalines.add(datalines);
}
public void run() {
Collections.sort(datalines,mycomparator);
synchronized(vector) {
vector.add(datalines);
}
}
}
您还需要同步对共享vector
集合的访问
然后,要等待ExecutorService中的所有线程完成使用,请执行以下操作:
executor.awaitTermination(30, TimeUnit.SECONDS);
我建议你实施以下计划,称为农场:
worker0
reader --> worker1 --> writer
...
workerN
因此,一个线程从文件中读取一个块,将其交给工作线程(最佳做法是让工作线程作为执行器服务
)对其进行排序,然后每个工作线程将其输出发送到写入线程以放入临时文件
编辑:好的,我已经查看了您的代码。若要解决共享的数据线
的问题,您可以为存储线程需要排序的当前数据线
数组的每个线程指定一个私有成员:
public class ThreadTask implements Runnable {
private List datalines = new ArrayList();
public ThreadTask(List datalines) {
this.datalines.add(datalines);
}
public void run() {
Collections.sort(datalines,mycomparator);
synchronized(vector) {
vector.add(datalines);
}
}
}
您还需要同步对共享vector
集合的访问
然后,要等待ExecutorService中的所有线程完成使用,请执行以下操作:
executor.awaitTermination(30, TimeUnit.SECONDS);
在三种情况下,并行顺序操作将提高性能:
您有一个CPU受限的应用程序,并且有多个核心可以在没有协调的情况下工作。在这种情况下,每个核心都可以完成其工作,您将看到线性加速。但是,如果您没有多个核心,多线程实际上会降低您的速度
您有一个IO绑定的应用程序,在该应用程序中,您通过独立的通道执行IO。应用程序服务器与多个套接字交互时就是这种情况。给定套接字上的数据相对来说不受其他套接字上发生的任何事情的影响。磁盘IO通常不是这种情况,除非您可以确保磁盘正常运行配给将分离主轴,并可能分离控制器。您通常不会在这里看到太多的加速,因为应用程序仍将花费大量时间等待。但是,它可以导致更干净的编程模型
将IO和CPU交错。在这种情况下,一个线程可以执行CPU密集型操作,而另一个线程则等待IO。如果有加速,则取决于应用程序中CPU和IO之间的平衡;在许多(大多数)情况下,与IO相比,CPU的贡献可以忽略不计
您描述案例3,并确定