代码之家  ›  专栏  ›  技术社区  ›  Amine Choukri

如何使用多线程来执行单个作业?

  •  0
  • Amine Choukri  · 技术社区  · 8 年前

    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);
        }
    }
    

    3 回复  |  直到 8 年前
        1
  •  0
  •   c0der    8 年前

    你要做的第一件事就是 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 .我希望有人能对此发表评论)。

        2
  •  1
  •   ggovan    8 年前

    你在打电话 T.join 启动线程后立即执行。 Thread#join 阻止当前线程,直到该线程完成。这意味着计算将在另一个线程上进行,但是您将不会获得并行性的任何好处,因为在另一个线程找到之前,您不会启动另一个线程。

    您可以启动所有线程,然后使用类似于 CountDownLatch 或者尝试使用 fork/join framework

        3
  •  0
  •   Fracdroid    8 年前