java - Why does multithreaded version take the same amount of time as single threaded version? -


i have following work queue implementation, use limit number of threads in use. works me adding number of runnable objects queue, , when ready begin, run "begin()". @ point not add more queue.

public class workqueue {      private final int nthreads;     private final poolworker[] threads;     private final linkedlist queue;     integer runcounter;     boolean hasbegun;      public workqueue(int nthreads) {         runcounter = 0;         this.nthreads = nthreads;         queue = new linkedlist();         threads = new poolworker[nthreads];         hasbegun = false;          (int = 0; < nthreads; i++) {             threads[i] = new poolworker();             threads[i].start();         }     }      public boolean isqueueempty() {         synchronized (queue) {             if (queue.isempty() && runcounter == 0) {                 return true;             } else {                 return false;             }         }     }      public void begin() {         hasbegun = true;         synchronized (queue) {             queue.notify();         }     }      public void add(runnable r) {         if (!hasbegun) {             synchronized (queue) {                 queue.addlast(r);                 runcounter++;             }         } else {             system.out.println("has begun executing. cannot add more jobs ");         }     }      private class poolworker extends thread {          public void run() {             runnable r;              while (true) {                 synchronized (queue) {                     while (queue.isempty()) {                         try {                             queue.wait();                         } catch (interruptedexception ignored) {                         }                     }                      r = (runnable) queue.removefirst();                 }                  // if don't catch runtimeexception,                  // pool leak threads                 try {                     r.run();                     synchronized (runcounter) {                         runcounter--;                     }                 } catch (runtimeexception e) {                     // might want log here                 }             }         }     } } 

this runnable use keep track of when jobs on work queue have finished:

public class queuewatcher implements runnable {      private thread t;     private string threadname;     private workqueue wq;      public queuewatcher(workqueue wq) {         this.threadname = "queuewatcher";         this.wq = wq;     }      @override     public void run() {         while (true) {             if (wq.isqueueempty()) {                 java.util.date date = new java.util.date();                 system.out.println("finishing , quiting at:" + date.tostring());                 system.exit(0);                 break;             } else {                 try {                     thread.sleep(1000);                 } catch (interruptedexception ex) {                     logger.getlogger(planegenerator.class.getname()).log(level.severe, null, ex);                 }             }         }     }      public void start() {         wq.begin();          system.out.println("starting " + threadname);         if (t == null) {             t = new thread(this, threadname);             t.setdaemon(false);             t.start();         }     } } 

this how use them:

workqueue wq = new workqueue(9); //get same results regardless of 1,2,3,8,9 queuewatcher qw = new queuewatcher(wq);  somerunnable1 sm1 = new somerunnable1(); somerunnable2 sm2 = new somerunnable2(); somerunnable3 sm3 = new somerunnable3(); somerunnable4 sm4 = new somerunnable4(); somerunnable5 sm5 = new somerunnable5();  wq.add(sm1); wq.add(sm2); wq.add(sm3); wq.add(sm4); wq.add(sm5);  qw.start(); 

but regardless of how many threads use, result same - takes 1m 10seconds complete. same when did single threaded version (when ran in main()). if set wq (1,2,3--9) threads between 1m8s-1m10s. problem ? jobs (somerunnable) have nothing each other , cannot block each other.

edit: each of runnables read image files filesystems , create new files in separate directory. new directory contains 400 output files.

edit: seems 1 thread doing work. made following changes:

i let woolworker store id

    poolworker(int id){         this.threadid = id;     } 

before running print id of worker.

                system.out.println(this.threadid + " got new task");                 r.run(); 

in workqueue constructor when creating poolworkers do:

    (int = 0; < nthreads; i++) {         threads[i] = new poolworker(i);         threads[i].start();     } 

but seems that thread 0 work, output always:

0 got new task

use queue.notifyall() start processing.

currently you're using queue.notify(), wake single thread. (the big clue pointed me when mentioned single thread running.)

also, synchronizing on integer runcounter isn't doing think it's doing - runcounter++ assigning new value integer each time, you're synchronizing on lot of different integer objects.


on side note, using raw threads , wait/notify paradigms complicated , error-prone best programmers - it's why java introduced java.util.concurrent package, provide threadsafe blockingqueue implementations , executors managing multithreaded apps.


Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -