【问题标题】:Java thread manipulation, parallel programmingJava线程操作,并行编程
【发布时间】:2015-03-27 09:59:23
【问题描述】:

我正在参加有关 java 编程的在线课程并遇到了这个问题,我正在研究使用线程进行并行编程。

我要制作一个程序的“四核”版本,该程序通过将和的范围分成四个相等的部分来计算 pi,并使用四个线程。

我尝试将它分成 4 个不同的线程并启动和加入每个线程。

public class quadCorePi extends Thread {

public static void main(String[] args) throws Exception {

          long startTime = System.currentTimeMillis();

          quadCorePi thread1 = new quadCorePi();
          thread1.begin = 0 ;
          thread1.end = numSteps / 4 ;

          quadCorePi thread2 = new quadCorePi();
          thread2.begin = 1 ;
          thread2.end = numSteps / 4 ;

          quadCorePi thread3 = new quadCorePi();
          thread3.begin = 2 ;
          thread3.end = numSteps / 4 ;

          quadCorePi thread4 = new quadCorePi();
          thread4.begin = numSteps / 4 ;
          thread4.end = numSteps ;



          thread1.start();
          thread2.start();
          thread3.start();
          thread4.start();

          thread1.join();
          thread2.join();
          thread3.join();
          thread4.join();

          long endTime = System.currentTimeMillis();

          double pi = step * (thread1.sum + thread2.sum + thread3.sum + thread4.sum);


          System.out.println("Value of pi: " + pi);

          System.out.println("Calculated in " +
                             (endTime - startTime) + " milliseconds");
      }

但它给了我错误的 pi 值,解释一下对于如何将工作拆分为线程非常有帮助。

这是给出的示例代码:

public class ParallelPi extends Thread {

  public static void main(String[] args) throws Exception {

      long startTime = System.currentTimeMillis();

      ParallelPi thread1 = new ParallelPi();
      thread1.begin = 0 ;
      thread1.end = numSteps / 2 ;

      ParallelPi thread2 = new ParallelPi();
      thread2.begin = numSteps / 2 ;
      thread2.end = numSteps ;

      thread1.start();
      thread2.start();

      thread1.join();
      thread2.join();

      long endTime = System.currentTimeMillis();

      double pi = step * (thread1.sum + thread2.sum) ;

      System.out.println("Value of pi: " + pi);

      System.out.println("Calculated in " +
                         (endTime - startTime) + " milliseconds");
  }

  static int numSteps = 10000000;

  static double step = 1.0 / (double) numSteps;

  double sum ;  
  int begin, end ;

  public void run() {

      sum = 0.0 ;

      for(int i = begin ; i < end ; i++){
          double x = (i + 0.5) * step ;
          sum += 4.0 / (1.0 + x * x);
      }
  }
  }

【问题讨论】:

  • 你确定你的计算是正确的吗?含义:当您在没有任何多线程的情况下调用它时,您的代码是否正常工作?
  • public class quadCorePi extends Thread,它运行之前给出的示例。
  • 首先,使用 java.util.concurrent 包而不是进行低级线程处理——这要容易得多。

标签: java multithreading


【解决方案1】:

您的限制不正确。这是更正后的代码:

public class QuadCorePi extends Thread {

    public static void main(String[] args) throws Exception {

        long startTime = System.currentTimeMillis();

        QuadCorePi thread1 = new QuadCorePi();
        thread1.begin = 0 ;
        thread1.end = numSteps / 4 ;

        QuadCorePi thread2 = new QuadCorePi();
        thread2.begin = numSteps / 4 ;
        thread2.end =  numSteps  / 2 ;

        QuadCorePi thread3 = new QuadCorePi();
        thread3.begin = numSteps / 2 ;
        thread3.end = 3 * numSteps / 4 ;

        QuadCorePi thread4 = new QuadCorePi();
        thread4.begin = 3 * numSteps / 4 ;
        thread4.end = numSteps ;

        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

        thread1.join();
        thread2.join();
        thread3.join();
        thread4.join();

        long endTime = System.currentTimeMillis();

        double pi = step * (thread1.sum + thread2.sum + thread3.sum + thread4.sum) ;

        System.out.println("Value of pi: " + pi);

        System.out.println("Calculated in " +
                (endTime - startTime) + " milliseconds");
    }

    static int numSteps = 10000000;

    static double step = 1.0 / (double) numSteps;

    double sum ;
    int begin, end ;

    public void run() {

        sum = 0.0 ;

        for(int i = begin ; i < end ; i++){
            double x = (i + 0.5) * step ;
            sum += 4.0 / (1.0 + x * x);
        }
    }
}

【讨论】:

  • 谢谢,是的,我的限制是错误的,感谢关于类名的提示。
【解决方案2】:

您确定计算器的限制没问题吗?不应该是:

thread2.begin = numSteps / 4 + 1 ;
thread2.end = numSteps / 2;

3 和 4 以此类推?

【讨论】:

  • 不完全。限制分为 4 个范围。
【解决方案3】:

一个改进是使用适当的 Java 并发库 - 这是代码在这种情况下的外观:

public class ParallelPi implements Callable<Double> {
    private static final ExecutorService executorService = 
            Executors.newFixedThreadPool(4);
    private static final int numSteps = 10000000;
    private static final double step = 1.0 / (double) numSteps;

    private final int begin, end;

    public ParallelPi(int begin, int end) {
        this.begin = begin;
        this.end = end;
    }

    public static void main(String[] args) throws Exception {
        long startTime = System.currentTimeMillis();

        List<Future<Double>> results = executorService.invokeAll(Arrays.asList(
                new ParallelPi(0, numSteps / 4), 
                new ParallelPi(numSteps / 4, numSteps / 2),
                new ParallelPi(numSteps / 2, 3 * numSteps / 4),
                new ParallelPi(3 * numSteps / 4, numSteps)));

        double pi = 0;
        for(Future<Double> result: results) {
            pi += result.get();
        }
        pi *= step;

        long endTime = System.currentTimeMillis();

        System.out.println("Value of pi: " + pi);
        System.out.println("Calculated in " + 
                (endTime - startTime) + " milliseconds");
    }

    @Override
    public Double call() throws Exception {
        double sum = 0.0;

        for (int i = begin; i < end; i++) {
            double x = (i + 0.5) * step;
            sum += 4.0 / (1.0 + x * x);
        }
        return sum;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 2020-02-20
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    相关资源
    最近更新 更多