下面的代码用于分形曼德博。它工作得很好,但是现在我想在其上使用线程的概念。结果应该相同,但是该工作必须由多个线程+10完成。
这是我的代码:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
public class test extends JFrame {
private final int MAX_ITER = 570;
private final double ZOOM = 150;
private BufferedImage I;
private double zx, zy, cX, cY, tmp;
private static int x,y;
public test() throws InterruptedException {
super("Mandelbrot Set");
setBounds(100, 100, 800, 600);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
I = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
for ( y = 0; y < getHeight(); y++) {
for ( x = 0; x < getWidth(); x++) {
Thread T = new Thread() {//*******
public void run() {
zx = zy = 0;
cX = (x - 400) / ZOOM;
cY = (y - 300) / ZOOM;
int iter = MAX_ITER;
while (zx * zx + zy * zy < 4 && iter > 0) {
tmp = zx * zx - zy * zy + cX;
zy = 2.0 * zx * zy + cY;
zx = tmp;
iter--;
}
I.setRGB(x, y, iter | (iter << 8));
System.out.println(Thread.currentThread().getId());
}
};//*******
T.start();//********
T.join();//**********
}
}
}
@Override
public void paint(Graphics g) {
g.drawImage(I, 0, 0, this);
}
public static void main(String[] args) throws InterruptedException {
new test().setVisible(true);
}
}
我尝试实例化循环中的线程,但没有得到想要的结果 有什么建议吗?
答案 0 :(得分:1)
启动线程后,您正在立即调用T.join
。 Thread#join
阻止当前线程,直到该线程完成。这意味着计算将在另一个线程上进行,但是您将无法获得并行性的好处,因为只有在该线程结束后才启动另一个线程。
您可以使用CountDownLatch
之类的东西来启动所有线程并等待它们一起完成,或者尝试使用fork/join framework
答案 1 :(得分:0)
您的代码看起来将计算出正确的值,但是您需要在所有线程完成后绘制图像才能实际看到结果。现在,只需在线程末尾调用repaint即可刷新屏幕WxH时间。为避免不必要的渲染,您可以保留一个全局计数器,该计数器在进入线程时增加,而在退出线程时减少。当计数器变为0时,重新粉刷。
答案 2 :(得分:0)
您要做的第一件事就是花费EDT的漫长过程。为此,请使用SwingWorker:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
public class Test extends JFrame {//see https://www.javatpoint.com/java-naming-conventions
private final int MAX_ITER = 570;
private final double ZOOM = 150;
private BufferedImage bImage;
public Test() throws InterruptedException {
super("Mandelbrot Set");
setBounds(100, 100, 800, 600);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
bImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
new Draw().execute();
}
@Override
public void paint(Graphics g) {
g.drawImage(bImage, 0, 0, this);
}
public static void main(String[] args) throws InterruptedException {
new Test().setVisible(true);
}
class Draw extends SwingWorker<Void, Void>{
private double zx, zy, cX, cY, tmp;
private int x,y;
@Override
protected Void doInBackground() throws Exception {
for ( y = 0; y < getHeight(); y++) {
for ( x = 0; x < getWidth(); x++) {
zx = zy = 0;
cX = (x - 400) / ZOOM;
cY = (y - 300) / ZOOM;
int iter = MAX_ITER;
while ((((zx * zx) + (zy * zy)) < 4) && (iter > 0)) {
tmp = ((zx * zx) - (zy * zy)) + cX;
zy = (2.0 * zx * zy) + cY;
zx = tmp;
iter--;
}
bImage.setRGB(x, y, iter | (iter << 8));
}
Thread.sleep(50); //added to slow down and demonstrate painting
repaint();
}
return null;
}
}
}
完成后,您可以创建多个SwingWorker
来完成工作。例如:
public class Test extends JFrame {//see https://www.javatpoint.com/java-naming-conventions
private final int MAX_ITER = 570;
private final double ZOOM = 150;
private volatile BufferedImage bImage;
public Test() throws InterruptedException {
super("Mandelbrot Set");
setBounds(100, 100, 800, 600);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
bImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < getHeight(); y++) {
new Draw(y).execute();
}
}
@Override
public void paint(Graphics g) {
g.drawImage(bImage, 0, 0, this);
}
public static void main(String[] args) throws InterruptedException {
new Test().setVisible(true);
}
class Draw extends SwingWorker<Void, Void>{
private double zx, zy, cX, cY, tmp;
private int x,y;
Draw(int y){
this.y = y;
}
@Override
protected Void doInBackground() throws Exception {
for ( x = 0; x < getWidth(); x++) {
zx = zy = 0;
cX = (x - 400) / ZOOM;
cY = (y - 300) / ZOOM;
int iter = MAX_ITER;
while ((((zx * zx) + (zy * zy)) < 4) && (iter > 0)) {
tmp = ((zx * zx) - (zy * zy)) + cX;
zy = (2.0 * zx * zy) + cY;
zx = tmp;
iter--;
}
bImage.setRGB(x, y, iter | (iter << 8));
}
Thread.sleep(50); //added to slow down and demonstrate painting
repaint();
return null;
}
}
}
(我不确定BufferedImage bImage
是否需要volatile
。我希望有人对此发表评论。)