multithreading - Java: Why/what are these threads monitoring? -
i have multithreaded java application splits image 4 chunks, 4 threads (i have quad-core cpu) each work on individual chunk of image, converting grayscale.
i found quite slow reason, used netbeans profiler , found threads "monitoring" (waiting) quite lot. example,
(green = running, red = monitoring)
i experimented different numbers of threads, e.g. 2, , found still happened (the time didn't happen 1 thread).
inside threads, commented out bits of code until narrowed "big delay" down statement:
newimage.setrgb(i,j,newcolor.getrgb()); // write new value pixel
if commented out, code runs (almost 5x) faster, , there no thread monitoring:
so why 1 line cause delay? color library (alongside bufferedimage)? right i'm going try , array of ints rgb values instead of using color object , see how goes.
here source code:
pixelsmanipulation.java (main class):
public final class pixelsmanipulation{ private static sequential sequentialgrayscaler = new sequential(); public static void main(string[] args) throws filenotfoundexception, ioexception, interruptedexception { file file = new file("src/pixelsmanipulation/hiresimage.jpg"); fileinputstream fis = new fileinputstream(file); bufferedimage image = imageio.read(fis); //reading image file int rows = 2; // 2 rows , 2 cols split image quarters int cols = 2; int chunks = rows * cols; // 4 chunks, 1 each quarter of image int chunkwidth = image.getwidth() / cols; // determines chunk width , height int chunkheight = image.getheight() / rows; int count = 0; bufferedimage imgs[] = new bufferedimage[chunks]; // array hold image chunks (int x = 0; x < rows; x++) { (int y = 0; y < cols; y++) { //initialize image array image chunks imgs[count] = new bufferedimage(chunkwidth, chunkheight, image.gettype()); // draws image chunk graphics2d gr = imgs[count++].creategraphics(); // create image use gr.drawimage(image, 0, 0, chunkwidth, chunkheight, chunkwidth * y, chunkheight * x, chunkwidth * y + chunkwidth, chunkheight * x + chunkheight, null); gr.dispose(); } } //writing mini images image files (int = 0; < imgs.length; i++) { imageio.write(imgs[i], "jpg", new file("img" + + ".jpg")); } system.out.println("mini images created"); // start threads respective quarters (chunks) of image work on // have quad-core machine, can use 4 threads on cpu parallel parallelgrayscaler = new parallel("thread-1", imgs[0]); parallel parallelgrayscaler2 = new parallel("thread-2", imgs[1]); parallel parallelgrayscaler3 = new parallel("thread-3", imgs[2]); parallel parallelgrayscaler4 = new parallel("thread-4", imgs[3]); // sequential: long starttime = system.currenttimemillis(); sequentialgrayscaler.converttograyscale(image); long stoptime = system.currenttimemillis(); long elapsedtime = stoptime - starttime; system.out.println("sequential code executed in " + elapsedtime + " ms."); // multithreaded (parallel): starttime = system.currenttimemillis(); parallelgrayscaler.start(); parallelgrayscaler2.start(); parallelgrayscaler3.start(); parallelgrayscaler4.start(); // main waits threads finish program doesn't "end" (i.e. stop measuring time) before threads finish parallelgrayscaler.join(); parallelgrayscaler2.join(); parallelgrayscaler3.join(); parallelgrayscaler4.join(); stoptime = system.currenttimemillis(); elapsedtime = stoptime - starttime; system.out.println("multithreaded (parallel) code executed in " + elapsedtime + " ms."); } }
parallel.java:
// let each of 4 threads work on different quarter of image public class parallel extends thread{//implements runnable{ private string threadname; private static bufferedimage myimage; // calling "my" image because each thread have own unique quarter of image work on private static int width, height; // image params parallel(string name, bufferedimage image){ threadname = name; system.out.println("creating "+ threadname); myimage = image; width = myimage.getwidth(); height = myimage.getheight(); } public void run(){ system.out.println("running " + threadname); // pixel pixel (for our quarter of image) (int j = 0; j < height; j++){ (int = 0; < width; i++){ // traversing image , converting rgb values (doing same thing sequential code on smaller scale) color c = new color(myimage.getrgb(i,j)); int red = (int)(c.getred() * 0.299); int green = (int)(c.getgreen() * 0.587); int blue = (int)(c.getblue() * 0.114); color newcolor = new color(red + green + blue, red + green + blue, red + green + blue); myimage.setrgb(i,j,newcolor.getrgb()); // write new value pixel } } file output = new file("src/pixelsmanipulation/"+threadname+"grayscale.jpg"); // put in "lower level" folder can see in project view try { imageio.write(newimage, "jpg", output); } catch (ioexception ex) { logger.getlogger(parallel.class.getname()).log(level.severe, null, ex); } system.out.println("thread " + threadname + " exiting. ---"); } }
i beginner @ threading in java (as using bufferedimage), curious why it's slow.
why parallel.myimage
static? cause threads share same image. might explain why waiting on each other.
Comments
Post a Comment