2016-04-28 31 views
2

任何人都可以告訴我這段代碼有什麼問題,我試圖在Mandelbrot程序中實現4個線程。文件中圖像的前半部分不是渲染。謝謝!Java中的Mandelbrot使用4線程

/* 
    * 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個不同的線程中被調用。

這是因爲你的代碼結束時的其他情況。說,例如me爲1。當它爲1時,將在if (me == 1)語句執行代碼,它也將在結束執行的代碼,作爲me不等於2

爲了解決這個問題,我將推薦使用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; 
    }