使用线程从文件进行Java复杂计算(并发)

使用线程从文件进行Java复杂计算(并发),java,parallel-processing,Java,Parallel Processing,所以我有文本文件,我可以用我的代码解析,并计算空间中的一些原子。问题是我必须使用线程使程序并行,我不知道如何在每个线程中传递文本文件 如果我尝试执行类似于double kx=console.nextDouble()的操作它无法识别控制台是什么,因为它的扫描器对象位于main()中。我错过了什么 (注意:严格来说,不必直接使用线程;我可以使用fork-join-pool等) 公共类NBodyBH{ //设置值以模拟实体的秒数 静态最终执行时间=100; 静态最终布尔图=假; 公共静态void ma

所以我有文本文件,我可以用我的代码解析,并计算空间中的一些原子。问题是我必须使用线程使程序并行,我不知道如何在每个线程中传递文本文件

如果我尝试执行类似于
double kx=console.nextDouble()的操作
它无法识别控制台是什么,因为它的
扫描器
对象位于
main()
中。我错过了什么

(注意:严格来说,不必直接使用线程;我可以使用fork-join-pool等)

公共类NBodyBH{
//设置值以模拟实体的秒数
静态最终执行时间=100;
静态最终布尔图=假;
公共静态void main(字符串[]args)引发FileNotFoundException{
字符串fname=args[0];
FileInputStream为=新FileInputStream(新文件(fname));
系统设置(is);
扫描仪控制台=新扫描仪(System.in);
最终双dt=0.1;//时间量
int N=console.nextInt();//粒子数
double radius=console.nextDouble();//宇宙半径
//下面是我想比较的部分
Body[]Body=新Body[N];//N个Body的数组
对于(int i=0;i
我相信你要找的是。它是在Java7中引入的,用于对文件进行异步操作

虽然您是说您将运行一个复杂的计算,因此可能时间密集型任务是计算本身而不是文件读取,但您可以在主线程中读取文件并使用并行性来运行复杂的计算

List<Integer> calculationResults = bodies.parallelStream()
                                         .map(doComplexCalculation)
                                         .collect(toList())
List calculationResults=body.parallelStream()
.map(doComplexCalculation)
.collect(toList())

在本例中,我假设计算返回一个
整数
,并且
实体
是一个
集合
,类似于
列表
,但根据需要进行调整。

我相信您正在寻找的是。它是在Java7中引入的,用于对文件进行异步操作

虽然您是说您将运行一个复杂的计算,因此可能时间密集型任务是计算本身而不是文件读取,但您可以在主线程中读取文件并使用并行性来运行复杂的计算

List<Integer> calculationResults = bodies.parallelStream()
                                         .map(doComplexCalculation)
                                         .collect(toList())
List calculationResults=body.parallelStream()
.map(doComplexCalculation)
.collect(toList())

在本例中,我假设计算返回一个
整数
,并且
body
是一个
集合
类似于
列表
,但根据需要调整它。

将文件传递给每个线程听起来是个坏主意。然后,您必须协调哪个线程读取哪些数据,这将是不必要的复杂,或者(更可能的是),每个线程都需要所有数据,而让每个线程重新读取文件是低效的

首先,读取所有数据。然后将需要的数据传递给每个线程

不要在
中将新的
文件输入流
分配给
系统。只需直接使用它创建一个
扫描仪

Scanner input = new Scanner(Paths.get(arg[0]));
...
List<Body> bodies = new ArrayList<>(N);
for (int i = 0; i < N; ++i) {
   ...
   bodies.add(new Body(...));
}
for (int step = 0; step < 10; ++step) { /* Simulate 10 time steps, or whatever. */
    List<Body> next = bodies.parallelStream() /* Here's your threads. */
        .map(body -> step(body, dt, bodies))
        .collect(Collectors.toList());
    /* Render new state */
    ...
    bodies = next; /* Throw away your old state. */
}
Scanner input=新的扫描仪(path.get(arg[0]);
...
列表主体=新的ArrayList(N);
对于(int i=0;i步骤(实体、dt、实体))
.collect(Collectors.toList());
/*呈现新状态*/
...
身体=下一步;/*扔掉你的旧状态*/
}
这里,
step()
是您需要编写的函数。如果我猜对了你在做什么,它会根据其他人的位置创建一个身体克隆体,具有新的位置和速度。如果可以修改
主体
类的代码,则此方法可能是该类的成员


必须小心不要修改“当前”实体,而只为每个实体创建替换。这维护了
并行性的“非干扰”要求。每个时间步的计算都需要O(N2)个时间,因为每个实体(N)的每个新状态取决于每个其他实体(×N)的状态。

将文件传递给每个线程听起来是个坏主意。然后,您必须协调哪个线程读取哪些数据,这将是不必要的复杂,或者(更可能的是),每个线程都需要所有数据,而让每个线程重新读取文件是低效的

首先,读取所有数据。然后将需要的数据传递给每个线程

不要在
中将新的
文件输入流
分配给
系统。只需直接使用它创建一个
扫描仪

Scanner input = new Scanner(Paths.get(arg[0]));
...
List<Body> bodies = new ArrayList<>(N);
for (int i = 0; i < N; ++i) {
   ...
   bodies.add(new Body(...));
}
for (int step = 0; step < 10; ++step) { /* Simulate 10 time steps, or whatever. */
    List<Body> next = bodies.parallelStream() /* Here's your threads. */
        .map(body -> step(body, dt, bodies))
        .collect(Collectors.toList());
    /* Render new state */
    ...
    bodies = next; /* Throw away your old state. */
}
Scanner input=新的扫描仪(path.get(arg[0]);
...
列表主体=新的ArrayList(N);
对于(int i=0;i步骤(实体、dt、实体))
.collect(Collectors.toList());
/*呈现新状态*/
...
身体=下一步;/*扔掉你的旧状态*/
}