2016-04-28 10 views
2

Mandelbrotプログラムに4つのスレッドを実装しようとしたこのコードで何が間違っているか教えてください。ファイル内のイメージの前半はレンダリングされません。ありがとう!Javaの4つのスレッドを使用したMandelbrot

/* 
    * To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package Week2; 

/** 
* 
* @author Alex Humphris 
*/ 
import java.awt.Color; 
import java.awt.image.BufferedImage; 

import javax.imageio.ImageIO; 

import java.io.File; 

public class ParallelMandelbrot4 extends Thread { 

final static int N = 4096; 
final static int CUTOFF = 100; 

static int[][] set = new int[N][N]; 

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

    // Calculate set 
    long startTime = System.currentTimeMillis(); 

    ParallelMandelbrot4 thread0 = new ParallelMandelbrot4(0); 
    ParallelMandelbrot4 thread1 = new ParallelMandelbrot4(1); 
    ParallelMandelbrot4 thread2 = new ParallelMandelbrot4(2); 
    ParallelMandelbrot4 thread3 = new ParallelMandelbrot4(3); 

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

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

    long endTime = System.currentTimeMillis(); 

    System.out.println("Calculation completed in " 
      + (endTime - startTime) + " milliseconds"); 

    // Plot image 
    BufferedImage img = new BufferedImage(N, N, 
      BufferedImage.TYPE_INT_ARGB); 

    // Draw pixels 
    for (int i = 0; i < N; i++) { 
     for (int j = 0; j < N; j++) { 

      int k = set[i][j]; 

      float level; 
      if (k < CUTOFF) { 
       level = (float) k/CUTOFF; 
      } else { 
       level = 0; 
      } 
      Color c = new Color(0, level, 0); // Green 
      img.setRGB(i, j, c.getRGB()); 
     } 
    } 

    // Print file 
    ImageIO.write(img, "PNG", new File("Mandelbrot.png")); 
} 

int me; 

public ParallelMandelbrot4(int me) { 
    this.me = me; 
} 

public void run() { 

    int begin, end; 

    if (me == 0) { 
     begin = 0; 
     end = (N/4) * 1; 
    } 
    if (me == 1) { 
     begin = (N/4) * 1; 
     end = (N/4) * 2; 
    } 
    if (me == 2) { 
     begin = (N/4) * 2; 
     end = (N/4) * 3; 
    } else { // me == 1 
     begin = (N/4) * 3; 
     end = N; 
    } 

    for (int i = begin; i < end; i++) { 
     for (int j = 0; j < N; j++) { 

      double cr = (4.0 * i - 2 * N)/N; 
      double ci = (4.0 * j - 2 * N)/N; 

      double zr = cr, zi = ci; 

      int k = 0; 
      while (k < CUTOFF && zr * zr + zi * zi < 4.0) { 

       // z = c + z * z 
       double newr = cr + zr * zr - zi * zi; 
       double newi = ci + 2 * zr * zi; 

       zr = newr; 
       zi = newi; 

       k++; 
      } 

      set[i][j] = k; 
     } 
    } 
} 

} 

答えて

2

run()文にエラーがあります。 (me == 3)のifステートメントを追加すると、イメージ全体がレンダリングされますが、以前はelseステートメントが3つの異なるスレッドで呼び出されていました。

これは、コードの最後にelseがあるためです。私は、それが1であるとき、それはif (me == 1)文でコードを実行します。1.で、meはこの問題を解決するには2

と等しくないとして、それはまた、最後にコードを実行しますたとえばmeのために言ってやりますif elseステートメントを使用することをお勧めします。

int begin = 0, end = 0; 

    if (me == 0) { 
     begin = 0; 
     end = (N/4) * 1; 
    } 
    else if (me == 1) { 
     begin = (N/4) * 1; 
     end = (N/4) * 2; 
    } 
    else if (me == 2) { 
     begin = (N/4) * 2; 
     end = (N/4) * 3; 
    } 
    else if (me == 3) { 
     begin = (N/4) * 3; 
     end = N; 
    } 
+0

ありがとうございました!私は新しいコンセプトを学んでいるので、それが馬鹿だと思っていました。 – Alexmh

0

マルチスレッド部分はほぼ正しいです。それはいくつかの問題があったコンストラクタです。 meを最終的なプライベート変数にすることを検討する必要があります。 @ Skepterの答えは正しい。これは私のIDEで見える方法で、あなたが使用しているif-elseのファンキーな考えを私に与えました。 enter image description here

動作するはずですので、それを修正する:

private final int me; 

public ParallelMandelbrot4(int me) { 
    this.me = me; 
} 

public void run() { 

    int begin, end; 

    if (me == 0) { 
     begin = 0; 
     end = (N/4) * 1; 
    } 
    else if (me == 1) { 
     begin = (N/4) * 1; 
     end = (N/4) * 2; 
    } 
    else if (me == 2) { 
     begin = (N/4) * 2; 
     end = (N/4) * 3; 
    } else { // me == 3 
     begin = (N/4) * 3; 
     end = N; 
    } 
関連する問題