java并行计算圆周率
时间: 2023-11-10 21:56:36 浏览: 157
要在Java中进行并行计算圆周率,可以使用多线程和并行算法。下面是一种常见的方法:
1. 首先,将圆周率计算问题分解为多个子问题,每个子问题计算一部分圆周率值。
2. 使用Java的多线程机制,创建一个线程池,并将每个子问题分配给一个线程进行计算。
3. 每个线程独立计算其分配的子问题,并累积最终的结果。
4. 最后,将所有线程的结果合并,得出最终的圆周率值。
这种方法充分利用了多核处理器的并行能力,可以加速圆周率的计算过程。
相关问题
用java串行和并行实现圆周率
首先需要了解圆周率的计算方法。一种常用的方法是蒙特卡罗方法,即生成一组随机点,统计其中落在单位圆内的点数,通过点数比上总数得到圆内面积与正方形面积的比值,再乘以4即可得到圆周率的近似值。
在Java中,可以使用串行和并行两种方式实现该方法。
串行实现:
```
public static double calculatePiSerial(long numThrows) {
long inCircle = 0;
for (long i = 0; i < numThrows; i++) {
double x = Math.random();
double y = Math.random();
if (x*x + y*y <= 1) {
inCircle++;
}
}
return 4.0 * inCircle / numThrows;
}
```
并行实现:
```
public static double calculatePiParallel(long numThrows) {
long inCircle = LongStream.range(0, numThrows)
.parallel()
.filter(i -> {
double x = Math.random();
double y = Math.random();
return x*x + y*y <= 1;
})
.count();
return 4.0 * inCircle / numThrows;
}
```
在并行实现中,使用了Java 8中的Stream API和并行流特性,将随机点的生成和落在圆内的判断并行处理,提高了计算效率。
需要注意的是,在使用并行流时,需要保证随机数的生成是线程安全的,可以使用ThreadLocalRandom代替Math.random()实现。同时,需要在多核CPU上运行该程序才能发挥并行计算的优势。
hadoop集群实现圆周率串行和并行计算的完整java代码
下面是基于Hadoop分布式计算框架实现串行和并行计算圆周率的完整Java代码。
1. 串行版本
```java
import java.util.Random;
public class PiSerial {
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
Random random = new Random();
int count = 0;
for (int i = 0; i < n; ++i) {
double x = random.nextDouble();
double y = random.nextDouble();
if (x * x + y * y <= 1) {
count += 1;
}
}
double pi = 4.0 * count / n;
System.out.println("Pi: " + pi);
}
}
```
2. 并行版本
```java
import java.io.IOException;
import java.util.Random;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.DoubleWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
public class PiParallel {
public static class PiMapper extends Mapper<Object, Text, NullWritable, DoubleWritable> {
private final static DoubleWritable one = new DoubleWritable(1);
private final static NullWritable nullWritable = NullWritable.get();
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
int n = Integer.parseInt(value.toString());
Random random = new Random();
int count = 0;
for (int i = 0; i < n; ++i) {
double x = random.nextDouble();
double y = random.nextDouble();
if (x * x + y * y <= 1) {
count += 1;
}
}
double pi = 4.0 * count / n;
context.write(nullWritable, new DoubleWritable(pi));
}
}
public static class PiReducer extends Reducer<NullWritable, DoubleWritable, NullWritable, DoubleWritable> {
private final static NullWritable nullWritable = NullWritable.get();
public void reduce(NullWritable key, Iterable<DoubleWritable> values, Context context)
throws IOException, InterruptedException {
double sum = 0;
int count = 0;
for (DoubleWritable val : values) {
sum += val.get();
count += 1;
}
double pi = sum / count;
context.write(nullWritable, new DoubleWritable(pi));
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "pi");
job.setJarByClass(PiParallel.class);
job.setMapperClass(PiMapper.class);
job.setReducerClass(PiReducer.class);
job.setOutputKeyClass(NullWritable.class);
job.setOutputValueClass(DoubleWritable.class);
job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
TextInputFormat.addInputPath(job, new Path(args[0]));
TextOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
```
以上代码片段可能需要根据实际情况进行修改和调整。需要注意的是,在并行版本中,输入文件的每行表示总点数,而不是单个点的坐标。
阅读全文