In lab 5, you used multiple threads to create a single image. In this lab, you will use a single thread to create in parallel simulation multiple images.
Often in computing, there are a large number of tasks (or jobs) that need to run in parallel. (Think of a simulator, say, to predict weather, manage a video game, study physical models of the universe, solve large-scale economic problems etc.) Inevitably, there are an insufficient number of processors to run all the jobs at the same time. So computer simulation often means breaking a number of jobs into tiny pieces and scheduling them on a limited number of processors, in a way that approximates fully parallel execution. When we use threads, the pieces are broken off in real time by the Java scheduler, in a manner not entirely under our control. Some problems require the breaking to be done with more precision than the scheduler can manage. This week we will look at such a problem. We will see it has a very elegant solution, and that we can save ourselves some effort by hacking the AWT event dispatch queue.
To learn the basics of event processesing and scheduling by building an application that serializes a collection of parallel tasks.
Mandel program from lab 5. You will modify the program so that it works and looks like the applet below.
The applet has on the right side a radio box with two buttons (labeled "in" and "out"), surrounded by a border labeled "Zoom." On the left is a JPanel that renders a Mandelbrot set, starting from the center pixel and moving outward until the entire JPanel is painted. Click on the image, and a new image is drawn (again, starting from the center of the panel and
moving outward), where the center of the new image coincides with where the mouse clicked the old image, twice as large as the original image, if
"in" is selected, and half as large if the "out" button is on. Below the buttons, the magnification of the latest
image being drawn is shown.
Note that, if the image is clicked while it is being drawn, the new image will start to draw while the old image finishes, and the degree of magnification is relative to the magnification at the point clicked.
Now here's the catch: You may not create any new user threads to do this. Instead, you will use the event
dispatching thread to simulate parallel execution. The basic idea is to extend the Runnable class so that the run method generates the color for one pixel in one of the images, then right before dying creates a new Runnable object that will calculate the next point to be drawn and puts the new object onto the EventQueue by calling SwingUtilities.invokeLater(...).
Call your program Mandel2. It should run as a standalone program (i.e., not an applet) and must take two arguments, the width and height of the image in pixels. The initial drawing should be scaled in the same way as in lab 5. You are free to use whatever color scheme you like.
Runnable objects you use. You are basically
employing functional programming techniques for this lab, and in functional programming it is common for functions
to take a lot of arguments.
BufferedImage so that it keeps track of the current position (in the
Mandelbrot set) and magnification of each pixel.
repaint(). The nicest way to do this is to use a javax.swing.Timer.
In case you don't see the point of drawing the images on a single thread, here is a demo of an earlier version of this program that used multiple threads. Try running it and see that the drawing is erratic and not nearly as orderly and precise as in the demo above.
Runnables on the
event queue,
put them on the new queue, and write a dispatcher to dequeue and process them. You should use the main thread
to do this, so that you don't have to create any new threads. Call this program Mandel3.
| Attendance | 1 |
| Design and style | 3 |
| Activity 1 | 4 |
| Activity 2 | 2 |
| Total | 10 points |