Java 并行计算
我需要计算平均值并从一个大文件中提取一些数字的根:Java 并行计算,java,multithreading,concurrency,parallel-processing,future,Java,Multithreading,Concurrency,Parallel Processing,Future,我需要计算平均值并从一个大文件中提取一些数字的根: 1, 2, 3, 4, 5,\n 6, 7, 8, 9, 10,\n 11, 12, 13, 14,15,\n ... 代码如下: import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Scanner; public class App1{ int res, c; dou
1, 2, 3, 4, 5,\n
6, 7, 8, 9, 10,\n
11, 12, 13, 14,15,\n
...
代码如下:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class App1{
int res, c;
double mean, root;
ArrayList list = new ArrayList();
public App1() {
// einlesen
Scanner sc = null;
try {
sc = new Scanner(new File("file.txt")).useDelimiter("[,\\s]+");
} catch (FileNotFoundException ex) {
System.err.println(ex);
}
while (sc.hasNextInt()) {
list.add(sc.nextInt());
res += (int) list.get(c);
c++;
}
sc.close();
// Mean
mean = res / list.size();
// Root
root = Math.sqrt(mean);
System.out.println("Mean: " + mean);
System.out.println("Root: " + root);
}
public static void main(String[] args) {
App1 app = new App1();
}
}
有没有办法将其并行化
在计算平均值之前,我需要所有的数字,因此一个线程无法计算,而另一个线程仍在从文件中获取数字。提取根也是一样:如果还没有计算平均值,线程就无法从平均值中提取它
我想,这是一个解决方案吗?你可以并行计算平均值,因为平均值就是总和除以计数。没有理由不能将这些值并行求和,并对它们进行计数,然后再进行除法 考虑一个类:
public class PartialSum() {
private final int partialcount;
private final int partialsum;
public PartialSum(int count, int sum) {
partialsum = sum;
partialcount = count;
public int getCount() {
return partialcount;
}
public int getSum() {
return partialsum;
}
}
现在,这可能是未来的返回类型,如Future
因此,您需要做的是将文件拆分为多个部分,然后将这些部分发送到各个线程
每个线程计算一个PartialSum
。然后,当线程完成时,您可以:
int sum = 0;
int count = 0;
for(Future<PartialSum> partial : futures) {
PartialSum ps = partial.get();
sum += ps.getSum();
count += ps.getCount();
}
double mean = (double)sum / count;
double root = ....
int和=0;
整数计数=0;
对于(未来部分:期货){
PartialSum ps=partial.get();
sum+=ps.getSum();
count+=ps.getCount();
}
双平均值=(双)总和/计数;
双根=。。。。
您可以并行计算平均值,因为平均值只是总和除以计数。没有理由不能将这些值并行求和,并对它们进行计数,然后再进行除法
考虑一个类:
public class PartialSum() {
private final int partialcount;
private final int partialsum;
public PartialSum(int count, int sum) {
partialsum = sum;
partialcount = count;
public int getCount() {
return partialcount;
}
public int getSum() {
return partialsum;
}
}
现在,这可能是未来的返回类型,如Future
因此,您需要做的是将文件拆分为多个部分,然后将这些部分发送到各个线程
每个线程计算一个PartialSum
。然后,当线程完成时,您可以:
int sum = 0;
int count = 0;
for(Future<PartialSum> partial : futures) {
PartialSum ps = partial.get();
sum += ps.getSum();
count += ps.getCount();
}
double mean = (double)sum / count;
double root = ....
int和=0;
整数计数=0;
对于(未来部分:期货){
PartialSum ps=partial.get();
sum+=ps.getSum();
count+=ps.getCount();
}
双平均值=(双)总和/计数;
双根=。。。。
我认为这是可能的
要确保线程不会读入文件的另一个线程块太远,需要做一些修改,但是应该可以做到您必须事先接受一些关键的东西-您处理数据的速度不能超过从文件中读取数据的速度。所以,第一次阅读整个文件需要多长时间,并接受你不会在这方面有所改进
这就是说-您是否考虑过。您必须事先接受一些关键信息-您处理数据的速度将无法超过从文件中读取数据的速度。所以,第一次阅读整个文件需要多长时间,并接受你不会在这方面有所改进
也就是说,你考虑过一个。不,没有办法将其并行化。虽然您可以做一些看起来像是在使用线程的事情,但结果将过于复杂,但仍然以与以前相同的速度运行 这样做的原因是,文件访问是并且必须是单线程的,除了从文件读取之外,您所做的就是两个添加操作。因此,在最好的情况下,这些add操作可以并行化,但是由于这些操作几乎不需要执行时间,因此最多可以获得5%-10%的收益。线程的创建和维护会抵消(甚至更糟)这段时间 为了加快速度,您可以做的一件事是删除将内容放入列表的部分(假设以后不需要这些值)
不,这是无法并行的。虽然您可以做一些看起来像是在使用线程的事情,但结果将过于复杂,但仍然以与以前相同的速度运行 这样做的原因是,文件访问是并且必须是单线程的,除了从文件读取之外,您所做的就是两个添加操作。因此,在最好的情况下,这些add操作可以并行化,但是由于这些操作几乎不需要执行时间,因此最多可以获得5%-10%的收益。线程的创建和维护会抵消(甚至更糟)这段时间 为了加快速度,您可以做的一件事是删除将内容放入列表的部分(假设以后不需要这些值)
我对java多线程不太了解,无法回答这个问题。但并行读取文件的最佳方法是在一个线程中读取文件,并通过条件变量通知另一个线程进行处理。根据处理的复杂性,如果逻辑无法并行,则可能有多个线程执行此操作,