@@ -0,0 +1,3107 @@
+package mandelbrot.core;%0A%0Aimport javax.swing.*;%0Aimport java.awt.*;%0Aimport java.awt.event.ActionEvent;%0Aimport java.awt.event.ActionListener;%0Aimport java.awt.geom.Point2D;%0Aimport java.awt.image.BufferedImage;%0Aimport java.awt.image.WritableRaster;%0Aimport java.util.Observable;%0Aimport java.util.concurrent.ForkJoinPool;%0Aimport java.util.concurrent.ForkJoinTask;%0Aimport java.util.concurrent.RecursiveAction;%0A%0Apublic class Model extends Observable implements ActionListener %7B%0A%0A    // ==== Properties ====%0A%0A    private final Timer timer = new Timer(1000 / 30, this);%0A    private final ForkJoinPool pool = new ForkJoinPool();%0A%0A    private Point2D location = new Point2D.Double(-2.5, -1);%0A    private double scale = 1/200.;%0A%0A    private BufferedImage image;%0A    private Graphics2D g2d;%0A    private WritableRaster raster;%0A    private ForkJoinTask task;%0A%0A    // ==== Accessors ====%0A%0A    public synchronized Dimension getSize() %7B%0A        return new Dimension(this.image.getWidth(), this.image.getHeight());%0A    %7D%0A%0A    public synchronized void setSize(Dimension dimension) %7B%0A        this.image = new BufferedImage(dimension.width, dimension.height, BufferedImage.TYPE_3BYTE_BGR);%0A        this.g2d = this.image.createGraphics();%0A        this.raster = this.image.getRaster();%0A        draw();%0A        timer.start();%0A    %7D%0A%0A    public synchronized BufferedImage getImage() %7B%0A        return image;%0A    %7D%0A%0A    // ==== ActionListener Implementation ====%0A%0A    public void actionPerformed(ActionEvent e) %7B%0A        if (e.getSource() == timer) %7B%0A            setChanged();%0A            notifyObservers();%0A%0A            if (task != null && task.isDone()) %7B%0A                timer.stop();%0A            %7D%0A        %7D%0A    %7D%0A%0A    // ==== Private Helper Methods ====%0A%0A    private void draw() %7B%0A        if (task != null && !task.isDone()) %7B%0A            task.cancel(true);%0A        %7D%0A        task = pool.submit(new Calculation(0, this.image.getWidth() - 1));%0A        timer.start();%0A    %7D%0A%0A    // ==== Calculation Task ====%0A%0A    private class Calculation extends RecursiveAction %7B%0A        private int left, right;%0A%0A        public Calculation(int left, int right) %7B%0A            this.left = left;%0A            this.right = right;%0A        %7D%0A%0A        @Override%0A        protected void compute() %7B%0A            if (right - left %3E 20) %7B%0A                int middle = left + (right - left)/2;%0A                invokeAll(new Calculation(left, middle - 1),%0A                          new Calculation(middle, right));%0A            %7D else %7B%0A                for (int x = left; x %3C= right; ++x) %7B%0A                    for (int y = 0; y %3C image.getHeight(); ++y) %7B%0A                        double mx = x * scale + location.getX();%0A                        double my = y * scale + location.getY();%0A%0A                        int iter = Algorithm.escapeTime(mx, my, 10000);%0A                        int ia%5B%5D = new int%5B3%5D;%0A                        ia%5B0%5D = iter %25 256;%0A                        ia%5B1%5D = iter %25 256;%0A                        ia%5B2%5D = iter %25 256;%0A                        raster.setPixel(x, y, ia);%0A                    %7D%0A                %7D%0A            %7D%0A        %7D%0A    %7D%0A%7D%0A

Introduce a second model which utilizes simple thread stealing