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
Post a Comment