并行化基本的java任务

时间:2015-05-01 11:00:38

标签: java multithreading

我创建了一个简单的顺序java程序,它使用两种不同的方法(math.pow()和Fast Inverse Square Root)计算数字的平方根,以比较结果的准确性和完成时间。现在我需要并行化这个任务,这样一个线程使用math.pow计算逆平方根,另一个线程使用FISR计算它。我不确定如何解决这个问题,因为我看过的每个多线程示例都有两个线程处理单个问题的两半,而不仅仅是运行单独的任务。我的源代码如下:

package paralleltask;


public class ParallelTask {

    public static void main(String[] args) {
            System.out.println("Please enter the value:");
            Scanner userInputScanner = new Scanner(System.in);
            int userIn = userInputScanner.nextInt();
            long totalStart = System.nanoTime();
            long powStart = System.nanoTime();
            double testNum = Math.pow(userIn, -1.0/2);
            long powEnd = System.nanoTime();
            long powDuration = powEnd - powStart;
            long FISRStart = System.nanoTime();
            float xhalf = 0.5f*userIn;
            int i = Float.floatToIntBits(userIn);
            i = 0x5f3759df - (i>>1);
            Float x = Float.intBitsToFloat(i);
            x = x*(1.5f - xhalf*x*x);
            long FISREnd = System.nanoTime();
            long totalEnd = System.nanoTime();
            long totalDuration = totalEnd - totalStart;
            long FISRDuration = FISREnd - FISRStart;
            String testNumString = String.valueOf(testNum);
            String FISR = String.valueOf(x);
            System.out.println("The inverse square root using the math.pow() function is:");
            System.out.println(testNumString);
            System.out.println("It took " + powDuration + " milliseconds to complete");
            System.out.println("The inverse square root using the FISR function is:");
            System.out.println(FISR);
            System.out.println("It took " + FISRDuration + " milliseconds to complete");
            if (testNum > x) {
                System.out.println("The FISR approximation was " + (testNum - x) + " smaller than the math.pow() value.");
            }
            if (testNum < x) {
                System.out.println("The FISR approximation was " + (x - testNum) + " larger than the math.pow() value.");
            }
            System.out.println("The FISR function completed " + (powDuration - FISRDuration) + " milliseconds faster than math.pow");
            System.out.println("The total completion time was " + totalDuration + " milliseconds.");
        }

}

1 个答案:

答案 0 :(得分:3)

我不会将其称为并行化,而是运行两个并发任务(因为您不能使一个计算在多个线程中运行以使其更快,但在单独的线程中运行两个单独的计算) 。如果您想同时运行,可以使用Executor

首先,我会重构代码,将两个计算作为一个单独的任务:

public class MathPowCalculation implements Callable<Double> {
    private final int input;

    public MatPowCalculation(int input) {
        this.input = input;
    }

    @Override
    public Double call() throws Exception {
        // your calculation and time measurement and logging
        return result;
    }
}

与第二种算法相似。

然后,您可以同时启动两个计算并接收第一个可用结果:

int input = ...;
ExecutorService executor = Executors.newFixedThreadPool(2);
List<Future<Double>> results = executor.invokeAll(Arrays.asList(new MathPowCalculation(input), new FISRCalculation(input)));

for (Future<Double> result : results) {
    Double value = result.get();
    // do something with result value
}

executor.shutdown();

您也可以查看ExecutorCompletionService,它可能会使您的代码更简单。

但是,正如评论中提到的其他人一样,您无法获得可靠的结果。微基准测试(JVM JIT优化等)有一个完整的科学,如果你想获得有用的结果,你需要为此目的使用一个框架。