多线程Java [英] Multi-threading Java
问题描述
我正在尝试在我的Java Mandelbrot应用程序中实现多线程:
I am trying to implement multi-threading in my Java Mandelbrot application:
这是我到目前为止所做的:
This is what I have so far:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
public class MandelbrotSet {
private int numberOfIterations;
private double realMin;
private double realMax;
private double imaginaryMin;
private double imaginaryMax;
private int width;
private int height;
public BufferedImage image;
public Graphics2D imageGraphics;
public MandelbrotSet() {
// Set the width and the height
this.width = 600;
this.height = 400;
image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
imageGraphics = image.createGraphics();
this.realMin = -2.0;
this.realMax = 1;
this.imaginaryMin = -1;
this.imaginaryMax = 1;
this.numberOfIterations = 1000;
}
public Complex calculateComplexNumber(int x, int y) {
double realPart = realMin + x * (realMax - realMin) / (this.getWidth() - 1);
double imaginaryPart = imaginaryMax - y * (imaginaryMax - imaginaryMin) / (this.getHeight() - 1);
return new Complex(realPart, imaginaryPart);
}
public void calculateMandelbrotImagePoints() {
Thread[] threads = new Thread[4];
for (int i = 0; i < maxThreads; i++) {
threads[i] = new Thread(new MThread(i));
threads[i].start();
}
}
class MThread implements Runnable {
private int i;
public MThread(int i) {
this.i = i;
}
//Method uses the thread number to draw the mandelbrot in columns
public void run() {
for (int x = i; x < width; x += 4) {
for (int y = 0; y < height; y++) {
int n = 0;
Complex c = calculateComplexNumber(x, y);
Complex z = c;
while ((zNumber.modulusSquared() < 4.0D) && (n < numberOfIterations)) {
z = z.square();
z.add(c);
n++;
}
if (n == numberOfIterations) {
imageGraphics.setColor(Color.BLACK);
} else {
imageGraphics.setColor(Color.getHSBColor(n / 100.0F, 1, 1));
}
imageGraphics.drawLine(x,y,x,y);
}
}
}
}
}
正在出现的问题是,在绘制图像时,图像中会显示不正确的像素:
The problem that is occurring is that when the image is drawn incorrect pixels are displayed in the image:
当我检查一个帖子时类似于:
When I check a thread with something like:
threads[i].isAlive();
图像似乎成功显示,但图像需要更长时间(最多3倍)渲染。
the image seems to display successfully, however the image takes much longer (up to 3x as long) to render.
我想知道的两件事。
-
我在哪里我错了?
Where am I going wrong?
将Mandelbrots绘制为 BufferedImage
的最佳方法是什么?迭代次数(> 1000)?
What would be the best way for drawing Mandelbrots to a BufferedImage
for a large number of iterations (>1000)?
推荐答案
我希望他的是什么@Michael Chang建议。我调整了代码以在band中呈现。
I expect his is what @Michael Chang was suggesting. I've adjusted the code to render in bands.
请注意,我无法对此进行测试。我不熟悉Java图形。
Please note that I have not been able to test this. I am not familiar with Java graphics.
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
public class MandelbrotSet {
private int numberOfIterations;
private double realMin;
private double realMax;
private double imaginaryMin;
private double imaginaryMax;
private int width;
private int height;
public BufferedImage image;
public Graphics2D imageGraphics;
static final int nThreads = 4;
public MandelbrotSet(int width, int height) {
// Set the width and the height
this.width = width;
this.height = height;
image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
imageGraphics = image.createGraphics();
this.realMin = -2.0;
this.realMax = 1;
this.imaginaryMin = -1;
this.imaginaryMax = 1;
this.numberOfIterations = 1000;
}
public Complex calculateComplexNumber(int x, int y) {
double realPart = realMin + x * (realMax - realMin) / (width - 1);
double imaginaryPart = imaginaryMax - y * (imaginaryMax - imaginaryMin) / (height - 1);
return new Complex(realPart, imaginaryPart);
}
public void calculateMandelbrotImagePoints() {
Thread[] threads = new Thread[nThreads];
int bandHeight = height / nThreads;
for (int i = 0; i < nThreads; i++) {
BufferedImage band = new BufferedImage(width, bandHeight, BufferedImage.TYPE_4BYTE_ABGR);
threads[i] = new Thread(new MThread(band, i * bandHeight, bandHeight));
threads[i].start();
}
}
class MThread implements Runnable {
final BufferedImage band;
final Graphics2D g;
final int top;
final int height;
private MThread(BufferedImage band, int top, int height) {
this.band = band;
g = band.createGraphics();
this.top = top;
this.height = height;
}
@Override
public void run() {
for (int x = 0; x < width; x++) {
for (int y = top; y < top + height; y++) {
int n = 0;
Complex c = calculateComplexNumber(x, y);
Complex z = c;
while ((z.times(z).mod() < 4.0D) && (n < numberOfIterations)) {
z = z.times(z).plus(c);
n++;
}
if (n == numberOfIterations) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.getHSBColor(n / 100.0F, 1, 1));
}
g.drawLine(x, y-top, x, y-top);
}
}
// Do somehing to merge this band ino the main one.
// Not familiar with java graphics so this may be wrong.
imageGraphics.drawImage(band, null, 0, top);
}
}
}
这篇关于多线程Java的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!