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();
}
双平均值=(双)总和/计数;
双根=。。。。
我认为这是可能的

  • int offset=(文件大小/线程数)
  • 创建n个线程
  • 每个线程从偏移量*线程编号开始读取。例如,线程0从字节0开始读取,线程1从偏移量*1开始读取,线程2从偏移量*2开始读取
  • 如果线程数!=0,向前阅读,直到遇到换行符-从那里开始
  • 把每个线程的平均值加起来。保存到“线程平均值”或其他位置
  • 当所有线程完成时,总平均值=所有“线程\平均值”变量的平均值
  • 总平均变量的平方根
  • 它将需要一点混乱来确保线程不会读入文件的另一个线程块太远,但应该是可以做到的

    我认为这是可能的

  • int offset=(文件大小/线程数)
  • 创建n个线程
  • 每个线程从偏移量*线程编号开始读取。例如,线程0从字节0开始读取,线程1从偏移量*1开始读取,线程2从偏移量*2开始读取
  • 如果线程数!=0,向前阅读,直到遇到换行符-从那里开始
  • 把每个线程的平均值加起来。保存到“线程平均值”或其他位置
  • 当所有线程完成时,总平均值=所有“线程\平均值”变量的平均值
  • 总平均变量的平方根

  • 要确保线程不会读入文件的另一个线程块太远,需要做一些修改,但是应该可以做到

    您必须事先接受一些关键的东西-您处理数据的速度不能超过从文件中读取数据的速度。所以,第一次阅读整个文件需要多长时间,并接受你不会在这方面有所改进


    这就是说-您是否考虑过。

    您必须事先接受一些关键信息-您处理数据的速度将无法超过从文件中读取数据的速度。所以,第一次阅读整个文件需要多长时间,并接受你不会在这方面有所改进


    也就是说,你考虑过一个。

    不,没有办法将其并行化。虽然您可以做一些看起来像是在使用线程的事情,但结果将过于复杂,但仍然以与以前相同的速度运行

    这样做的原因是,文件访问是并且必须是单线程的,除了从文件读取之外,您所做的就是两个添加操作。因此,在最好的情况下,这些add操作可以并行化,但是由于这些操作几乎不需要执行时间,因此最多可以获得5%-10%的收益。线程的创建和维护会抵消(甚至更糟)这段时间

    为了加快速度,您可以做的一件事是删除将内容放入列表的部分(假设以后不需要这些值)


    不,这是无法并行的。虽然您可以做一些看起来像是在使用线程的事情,但结果将过于复杂,但仍然以与以前相同的速度运行

    这样做的原因是,文件访问是并且必须是单线程的,除了从文件读取之外,您所做的就是两个添加操作。因此,在最好的情况下,这些add操作可以并行化,但是由于这些操作几乎不需要执行时间,因此最多可以获得5%-10%的收益。线程的创建和维护会抵消(甚至更糟)这段时间

    为了加快速度,您可以做的一件事是删除将内容放入列表的部分(假设以后不需要这些值)


    我对java多线程不太了解,无法回答这个问题。但并行读取文件的最佳方法是在一个线程中读取文件,并通过条件变量通知另一个线程进行处理。根据处理的复杂性,如果逻辑无法并行,则可能有多个线程执行此操作,