Java 如何使用多线程加速计算?
我试图计算Pi,但我真正想要的是在使用多个线程时实现效率。算法很简单:我在单位正方形中随机生成点,然后计算有多少点在正方形内接的圆中。(更多信息请点击此处:) 我的想法是水平分割正方形,并为每个部分运行不同的线程。 但我得到的不是加速,而是延迟。你知道为什么吗?代码如下:Java 如何使用多线程加速计算?,java,multithreading,performance,Java,Multithreading,Performance,我试图计算Pi,但我真正想要的是在使用多个线程时实现效率。算法很简单:我在单位正方形中随机生成点,然后计算有多少点在正方形内接的圆中。(更多信息请点击此处:) 我的想法是水平分割正方形,并为每个部分运行不同的线程。 但我得到的不是加速,而是延迟。你知道为什么吗?代码如下: public class TaskManager { public static void main(String[] args) { int threadsCount = 3; int size = 10
public class TaskManager {
public static void main(String[] args) {
int threadsCount = 3;
int size = 10000000;
boolean isQuiet = false;
PiCalculator pi = new PiCalculator(size);
Thread tr[] = new Thread[threadsCount];
long time = -System.currentTimeMillis();
int i;
double s = 1.0/threadsCount;
int p = size/threadsCount;
for(i = 0; i < threadsCount; i++) {
PiRunnable r = new PiRunnable(pi, s*i, s*(1.0+i), p, isQuiet);
tr[i] = new Thread(r);
}
for(i = 0; i < threadsCount; i++) {
tr[i].start();
}
for(i = 0; i < threadsCount; i++) {
try {
tr[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
double myPi = 4.0*pi.getPointsInCircle()/pi.getPointsInSquare();
System.out.println(myPi + " time = " + (System.currentTimeMillis()+time));
}
}
public class PiRunnable implements Runnable {
PiCalculator pi;
private double minX;
private double maxX;
private int pointsToSpread;
public PiRunnable(PiCalculator pi, double minX, double maxX, int pointsToSpread, boolean isQuiet) {
super();
this.pi = pi;
this.minX = minX;
this.maxX = maxX;
this.pointsToSpread = pointsToSpread;
}
@Override
public void run() {
int n = countPointsInAreaInCircle(minX, maxX, pointsToSpread);
pi.addToPointsInCircle(n);
}
public int countPointsInAreaInCircle (double minX, double maxX, int pointsCount) {
double x;
double y;
int inCircle = 0;
for (int i = 0; i < pointsCount; i++) {
x = Math.random() * (maxX - minX) + minX;
y = Math.random();
if (x*x + y*y <= 1) {
inCircle++;
}
}
return inCircle;
}
}
public class PiCalculator {
private int pointsInSquare;
private int pointsInCircle;
public PiCalculator(int pointsInSquare) {
super();
this.pointsInSquare = pointsInSquare;
}
public synchronized void addToPointsInCircle (int pointsCount) {
this.pointsInCircle += pointsCount;
}
public synchronized int getPointsInCircle () {
return this.pointsInCircle;
}
public synchronized void setPointsInSquare (int pointsInSquare) {
this.pointsInSquare = pointsInSquare;
}
public synchronized int getPointsInSquare () {
return this.pointsInSquare;
}
}
公共类任务管理器{
公共静态void main(字符串[]args){
int-threadscont=3;
int size=10000000;
布尔值isQuiet=false;
PicalCalculator pi=新PiCalculator(尺寸);
线程tr[]=新线程[threadsCount];
长时间=-System.currentTimeMillis();
int i;
双s=1.0/threadsCount;
int p=尺寸/螺纹长度;
对于(i=0;i 如果(x*x+y*y您的线程可能正在战斗/等待同步的Math.random()
,您应该为每个线程创建一个java.util.random实例。在这种情况下,只有当您有多个核心/cpu时,才会发生多线程加速
从以下文件的javadoc:
此方法已正确同步
允许多个用户正确使用
但是,如果许多线程需要
一次生成伪随机数
速度快,可以减少争用
每个线程都有自己的
伪随机数发生器
下面是另一个main
方法,它使用java.util.concurrency
包,而不是手动管理线程并等待线程完成
public static void main(final String[] args) throws InterruptedException
{
final int threadsCount = Runtime.getRuntime().availableProcessors();
final int size = 10000000;
boolean isQuiet = false;
final PiCalculator pi = new PiCalculator(size);
final ExecutorService es = Executors.newFixedThreadPool(threadsCount);
long time = -System.currentTimeMillis();
int i;
double s = 1.0 / threadsCount;
int p = size / threadsCount;
for (i = 0; i < threadsCount; i++)
{
es.submit(new PiRunnable(pi, s * i, s * (1.0 + i), p, isQuiet));
}
es.shutdown();
while (!es.isTerminated()) { /* do nothing waiting for threads to complete */ }
double myPi = 4.0 * pi.getPointsInCircle() / pi.getPointsInSquare();
System.out.println(myPi + " time = " + (System.currentTimeMillis() + time));
}
这是我得到的新输出
3.1419284 time = 235
我想你可以使用Futures
,而不必在PicalCalculator
上进行太多的同步。你是在多核系统上运行的吗?我是在intel core 2 duo上运行的。他在加入之前就启动了所有这些系统,所以这没问题。如果你只有2个核,那么使用2个以上的核就没有用了线程。您的应用程序纯粹受CPU限制,因此,由于上下文切换的开销,线程数多于核心数只会降低速度。我在版本final int-threadscont=Runtime.getRuntime().availableProcessors();
中使用了以下内容
到Random
的本地实例,并获得以下输出3.1411296 time=253
Core i3 M350 2.27GHZ/8GB RAM
3.1419284 time = 235