/**
{{{ http://code.activestate.com/recipes/577158/ (r1)
*/
// <applet code="MandelbrotFractal"
width=800 height=600></applet>
// MandelbrotFractal.java (FB - 201003276)
// N Multi-threaded!
import java.applet.Applet;
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;
import java.lang.Thread;
//original program fixed up a bit
public class MandelbrotFractal2 extends Applet
{
Image img;
int
pix[]; // will be shared by all
threads
int
w,h,alpha;
int
maxThr = 10; // number of threads to run
int
count = 0;
int
count1 = 0;
// drawing area (must be xa<xb and ya<yb)
final double
xa = -2.0;
final double
xb = 1.0;
final double
ya = -1.5;
final double
yb = 1.5;
public void init()
{
w=getSize().width;
h=getSize().height;
alpha=255;
pix=new int[w*h];
maxThr = 1; <---Now
runs with various numbers of threads
manfr();
maxThr = 1;
manfr();
maxThr = 2;
manfr();
maxThr = 10;
manfr();
img=createImage(new
MemoryImageSource(w,h,pix,0,w));
}
// Use "synchronized" to
introduce mutex (mutex for
this class)
public
synchronized void incrementSync() <---Synchronized
method in outer class
{ uses mutex for outer class (global to program)
// count++;
int localCount =
count;
localCount++;
delay();
count = localCount;
}
public void incrementUnSync()
{
// count1++;
int localCount =
count1;
localCount++;
delay();
count1 = localCount;
}
public int delay()
{
int sum = 0;
for (int i=0;i<10000;i++)
sum += i;
return
sum; // so can't be optimized away
}
public void manfr()
{
long startTime = System.currentTimeMillis();
add(new JLabel("test"));
ManFrThread[] m = new ManFrThread[maxThr];
for(int i=0;i<maxThr;i++)
{
m[i]=new ManFrThread(i);
m[i].start();
}
// wait until all threads finished
try
{
for(int j=0;j<maxThr;j++)
m[j].join(); // wait for thread to finish
} catch (InterruptedException
ex) {
System.out.println("saw interrupt exception");
}
// beep to prove we got here--
java.awt.Toolkit.getDefaultToolkit().beep();
// to see this output, get a
"Java Console" window from
// Java toolbar icon (also can use
its x command to clear
// the .class cache if you
recompile this program)
System.out.println("Number
of threads: " + maxThr);
long timeInMillis = System.currentTimeMillis()
- startTime;
System.out.println("Run
Time in Millis: " + timeInMillis);
System.out.println("Final
sync count: " + count);
System.out.println("Final
unsync count: " + count1);
}
public void
paint(Graphics g)
{
g.drawImage(img,0,0,this);
}
class ManFrThread extends Thread <--
inner class for Thread code
{
int k; // id number of this thread
ManFrThread(int k)
{
this.k=k;
}
public
void run()
{
double
x0,x,y,a,b;
int red,green,blue;
int i,kx,ky,kc;
int imax=w*h;
// Each
thread only calculates its own share of pixels!
// Have each thread do a block of pixels--
for(i=k*(imax/maxThr);i<(k+1)*(imax/maxThr);i++)
{
kx=i%w;
ky=i/w; // simplified
a=(double)kx/w*(xb-xa)+xa;
b=(double)ky/h*(yb-ya)+ya;
x=a;
y=b;
incrementSync(); <--calls to increment in thread code
incrementUnSync();
for(kc=0;kc<256;kc++)
{
x0=x*x-y*y+a;
y=2*x*y+b;
x=x0;
if(x*x+y*y > 4)
{
// various color
palettes can be created here!
red=255-(kc%16)*16;
green=(16-kc%16)*16;
blue=(kc%16)*16;
pix[i]=(alpha<<24)|(red<<16)|(green<<8)|blue;
break;
}
}
}
}
}
}
Number of threads: 1
Run
Time in Millis: 5970
Final
sync count: 400000
Final
unsync count: 400000
Number
of threads: 1
Run
Time in Millis: 5876
Final
sync count: 800000
Final
unsync count: 800000
Number
of threads: 2
Run
Time in Millis: 3157
Final
sync count: 1200000
Final
unsync count: 1182728
Number
of threads: 10
Run
Time in Millis: 3109
Final
sync count: 1600000
Final
unsync count: 1437893