[英]How to use multiple thread to do a single job?
以下代碼適用於分形曼德羅。 它工作得很好,但是現在我想在其上使用線程的概念。 結果應該是相同的,但是工作必須由多個線程+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);
}
}
我試圖在循環中實例化線程,但沒有得到想要的建議結果?
您在啟動線程后立即調用T.join
。 Thread#join
阻塞當前線程,直到該線程完成。 這意味着計算將在另一個線程上進行,但是您將無法獲得並行性的任何好處,因為您不會在另一個線程結束之前啟動另一個線程。
您可以使用CountDownLatch
類的方法來啟動所有線程並等待它們一起完成,或者嘗試使用fork / join框架
您的代碼看起來將計算出正確的值,但是您需要在所有線程完成后才能繪制圖像以實際看到結果。 現在,只需在線程末尾調用repaint即可刷新屏幕WxH時間。 為避免不必要的渲染,您可以保留一個全局計數器,該計數器在進入線程時增加,而在退出線程時減少。 當計數器變為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
。希望有人對此發表評論)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.