It doesn't look like I'm going to have time to test the new
ThreadQueue anytime soon.  I did plug it in long enough to determine
that it broke my code that called getRunningThreads() since that
method is no longer present.  I didn't have time to  look for the new
method that I should use instead.  I should be able to get back to it
in a couple of weeks (I'm instructing a class in our software next
week).

regards,
Larry

On 5/30/07, Michaël Michaud <[EMAIL PROTECTED]> wrote:
>
> >Hei Saschachaël
> >
> >i got positive feedback from my colleaque on the changes of the
> >threading stuff.
> >If Michael aggrees too, you can commit
> >
> >
> As far as I'm concerned, I am really pleased to see Sascha's
> contribution to the core.
> OJ really needs contributions from skilled programmers :-) .
>
> Michaël
>
> >stefan
> >
> >Sascha L. Teichmann schrieb:
> >
> >
> >>Hi!
> >>
> >>Stefan Steiniger schrieb:
> >>
> >>
> >>>Similar to Landon I have never touched threading nor heared any lectures
> >>>or read books on it. Thus .. i dont know if it turns out to be good or bad.
> >>>But i know that making things more clean is good objective. Thus, i
> >>>support the changes. It would be good when we finally change the code,
> >>>that you also put into the code some docs or references where you
> >>>outline why somethings has changed. (actually I currently would opt to
> >>>leave the old code as comment and not to remove entirely)
> >>>
> >>>
> >>The ThreadQueue is JavaDoc'ed but I can add some
> >>design notes as well. Keeping old things as comments negates
> >>the existence of version control systems.
> >>CVS is exactly the time machine you for this.
> >>As I pointed out earlier having a ChangeLog would
> >>be nice to document motivations and backgrounds for a change. Simply
> >>generating a ChangeLog out of the commit messages is convenient but
> >>it does not uncover the true potential of such a 'log' file.
> >>
> >>
> >>
> >>>Due to my lack of knowledge i forwarded your email to a colleague who
> >>>developed a web-service based on JUMP (which runs on a server, see [1]),
> >>>an ajax client and recently did some multiprocessor experiments for the
> >>>web-services processing.
> >>>
> >>>
> >>I look forward to his comments.
> >>
> >>
> >>
> >>>I hope 1) he will look on your proposal and 2) you can wait some days
> >>>until he, Larry and Michael got an opinion.
> >>>
> >>>
> >>@Michael: You ask what to change. For the moment just replace
> >>ThreadQueue.java with one I've sent last. The first patches
> >>are addressing the problem with ThreadQueue limited to one
> >>Thread at a time (defaultRenderingThreadQueue in RenderingManger).
> >>You can apply these patches too, but they are not needed any
> >>longer. With next patch I'll send the this second thread queue
> >>will be removed from RenderingManager entirely.
> >>
> >>What to test? Doing your day-to-day is the best thing
> >>you can do. The most important thing is that the new one
> >>behaves exactly like the old one. The magic word is compatibility.
> >>I don't want to break the show. Use plug-ins, use many layers,
> >>use less layer, use db and WMS layers. Do all the fancy stuff
> >>you like to do. If the OJ freezes or something other looks odd
> >>just tell me. :-)
> >>
> >>- Sascha
> >>
> >>
> >>
> >>>Michaël Michaud schrieb:
> >>>
> >>>
> >>>>Sascha L. Teichmann a écrit :
> >>>>
> >>>>
> >>>>
> >>>>>Really back to topic:
> >>>>>
> >>>>>Find attached a replacement for ThreadQueue [1].
> >>>>>To use it just overwrite the original one.
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>Hi Sascha :
> >>>>
> >>>>I think that trying to have a cleaner and more simple code is an
> >>>>excellent goal, and I'd like to help, but I'm not sure I can understand
> >>>>all these thread issues.
> >>>>If you tell me exactly which classes I must replace (on ly ThreadQueue
> >>>>or also the pieces of code from your previous mail) and what kind of
> >>>>tests I should do (rendering different kind of layers ? mixing different
> >>>>kind of layers), I'll try to make some more tests on my desktop.
> >>>>
> >>>>Thanks, for the hard work
> >>>>
> >>>>Michaël
> >>>>
> >>>>
> >>>>
> >>>>>This one works for the real parallel case of
> >>>>>layer rendering too. Each time a thread finished
> >>>>>executing its Runnable it looks into the queue
> >>>>>if they are more jobs to do. This prevents unnecessary
> >>>>>thread creations/shutdowns. If the queue is empty
> >>>>>the worker thread is kept alive for 5 seconds waiting
> >>>>>for new jobs. This results in a kind of thread pooling.
> >>>>>
> >>>>>@Larry: I've isolated my implementation and the OJ
> >>>>>ThreadQueue and done a synthetic benchmark with a
> >>>>>larger number of jobs (10,000+). My implementation
> >>>>>works about two orders faster than the OJ one.
> >>>>>But this is of little meaning because OJ only
> >>>>>has to handle a number of jobs equal the number
> >>>>>of layers. This will hardly hit 10,000+ ;-)
> >>>>>But again: My mission is improve the structure not
> >>>>>primarily the speed.
> >>>>>
> >>>>>I've tested the new ThreadQueue to some extent but
> >>>>>I'am male(tm) after all ... potentially making mistakes.
> >>>>>It would be very kind if someone test it too.
> >>>>>
> >>>>>My next step will be some clean up in the RenderingManager [2].
> >>>>>I'am not sure that it is really needed to have two ThreadQueues
> >>>>>there. The effect of the single tread one can be easily
> >>>>>simulated with a data structure like the RunnableArrayList which
> >>>>>I've posted already.
> >>>>>
> >>>>>Any comments?
> >>>>>
> >>>>>Yours,
> >>>>> Sascha
> >>>>>
> >>>>>[1] com.vividsolutions.jump.workbench.ui.renderer.ThreadQueue
> >>>>>[2] com.vividsolutions.jump.workbench.ui.renderer.RenderingManager
> >>>>>
> >>>>>Sunburned Surveyor schrieb:
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>>Sascha,
> >>>>>>
> >>>>>>Please accept my sincerest aopologies. I'm afriad my American
> >>>>>>ignorance of other cultures is more than just a little obvious at
> >>>>>>times.
> >>>>>>
> >>>>>>I believe I have made the same mistake with Jan. :]
> >>>>>>
> >>>>>>Please be patient with me as I learn the details of cultures across
> >>>>>>the Pacific and Atalantic Oceans!
> >>>>>>
> >>>>>>The Sunburned Surveyor
> >>>>>>
> >>>>>>On 5/24/07, Sascha L. Teichmann <[EMAIL PROTECTED]> wrote:
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>>TNX, but for the records 'he' would be more suited in my case.
> >>>>>>>
> >>>>>>>'Sascha' is basically a Russian term of endearment for the
> >>>>>>>boys name 'Alexander' but it's also used as a girls name.
> >>>>>>>
> >>>>>>>BTW: 'Jan' is a girls name in the US too, isn't? ;-)
> >>>>>>>
> >>>>>>>- Sascha
> >>>>>>>
> >>>>>>>
> >>>>>>>Sunburned Surveyor schrieb:
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>>Sascha and Larry,
> >>>>>>>>
> >>>>>>>>I must admit that I am way over my head here. I haven't done much
> >>>>>>>>thread programming in Java. (Hopefully Stefan has!)
> >>>>>>>>
> >>>>>>>>Sascha wrote: "My primary goal is to simplify the
> >>>>>>>>threading code to make it more reliable in terms of time."
> >>>>>>>>
> >>>>>>>>This seems like an admirable goal to me. If Larry, or a similar
> >>>>>>>>programmer of his experience, agrees that this changes would be
> >>>>>>>>beneficial, I say we give Sascha a shot at it. It sounds like she has
> >>>>>>>>considered her changes carefully.
> >>>>>>>>
> >>>>>>>>Just my two cents.
> >>>>>>>>
> >>>>>>>>The Sunburned Surveyor
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>On 5/24/07, Sascha L. Teichmann <[EMAIL PROTECTED]> wrote:
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>>Hi Larry,
> >>>>>>>>>
> >>>>>>>>>short answer first: No, I don't have any benchmarks, yet.
> >>>>>>>>>
> >>>>>>>>>The long answer: My primary goal is to simplify the
> >>>>>>>>>threading code to make it more reliable in terms of time.
> >>>>>>>>>Gaining performance improvements would be a neat side effect.
> >>>>>>>>>
> >>>>>>>>>Background: Multi-threading may be fine for slow layers
> >>>>>>>>>which arrives later on the screen but for exporting
> >>>>>>>>>the data (to print/layout e.g) it would be nice to have
> >>>>>>>>>them arriving one after the other.
> >>>>>>>>>
> >>>>>>>>>My final goal is to have a simple switch between the normal
> >>>>>>>>>and the serial mode. To archive that I try to carefully
> >>>>>>>>>refactor the system doing little patches step by step
> >>>>>>>>>not to break it. Refactoring the ThreadQueue with it's
> >>>>>>>>>'flaws' seems a to be a good starting point to me.
> >>>>>>>>>
> >>>>>>>>>One reason for this change is the fact that you are able
> >>>>>>>>>to figure out if the default thread runs empty. But there
> >>>>>>>>>is no way to figure out when the last thread ends. That
> >>>>>>>>>are different things. A mechanism for this is planned.
> >>>>>>>>>
> >>>>>>>>>Sorry, if I've shadowed my true intentions to much. Maybe
> >>>>>>>>>I should discuss more before I send patches.  ;-)
> >>>>>>>>>
> >>>>>>>>>Back to the technical side:
> >>>>>>>>>
> >>>>>>>>>The patch needs some testing but I don't expect too much
> >>>>>>>>>performance improvement.
> >>>>>>>>>
> >>>>>>>>>A less intrusive alternative to bind the Runnables that go to the
> >>>>>>>>>default ThreadQueue into one thread is to create a container
> >>>>>>>>>which self is Runnable (see e.g. RunnableArrayList attached)
> >>>>>>>>>and put them into an instance of this class.
> >>>>>>>>>This container is put into multiRendererThreadQueue as a Runnable.
> >>>>>>>>>With this modification the defaultRendererThreadQueue can
> >>>>>>>>>be removed (multiRendererThreadQueue renamed to
> >>>>>>>>>defaultRendererThreadQueue). Only an idea ... I'm in discussion
> >>>>>>>>>mode now. ;-)
> >>>>>>>>>
> >>>>>>>>>- Sascha
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>Larry Becker schrieb:
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>>Hi Sascha,
> >>>>>>>>>>
> >>>>>>>>>> I read your comments and look at your code with interest.  It 
> >>>>>>>>>> appears
> >>>>>>>>>>to be an improved ThreadQueue implementation, but will require a 
> >>>>>>>>>>lot of
> >>>>>>>>>>testing to verify.  Before I invest this time, I would like to know 
> >>>>>>>>>>what
> >>>>>>>>>>problem it is solving.  I see your dislikes a - e, but these are not
> >>>>>>>>>>really problems, only architectural critiques.  Have you done any
> >>>>>>>>>>benchmarks that show that the new SingleThreadQueue speeds up
> >>>>>>>>>>rendering?  Your logical argument that it should be more efficient  
> >>>>>>>>>>is
> >>>>>>>>>>persuasive,  but  I have been surprised by Java before.
> >>>>>>>>>>
> >>>>>>>>>>respectfully,
> >>>>>>>>>>Larry Becker
> >>>>>>>>>>
> >>>>>>>>>>On 5/23/07, *Sascha L. Teichmann* <[EMAIL PROTECTED]
> >>>>>>>>>><mailto:[EMAIL PROTECTED]>> wrote:
> >>>>>>>>>>
> >>>>>>>>>>   Hi together,
> >>>>>>>>>>
> >>>>>>>>>>   as some of you may already know i have my dislikes against
> >>>>>>>>>>   ThreadQueue [1] (Hi, Larry!) see my mail [2]
> >>>>>>>>>>
> >>>>>>>>>>   a - It forks a new thread for any Runnable it processes.
> >>>>>>>>>>   b - It has an ugly busy wait loop inside.
> >>>>>>>>>>   c - The event listener for empty queue fires to often.
> >>>>>>>>>>   d - The default ThreadQueue is some kind of thread serializer.
> >>>>>>>>>>   e - The DB/WMS ThreadQueue has no public access.
> >>>>>>>>>>
> >>>>>>>>>>   Now I've written a sub class of ThreadQueue: SingleThreadQueue
> >>>>>>>>>>   (see attachment). This one deals with the issues a, b and d.
> >>>>>>>>>>   I also attached a patch against RenderingManager [3] to handle e.
> >>>>>>>>>>
> >>>>>>>>>>   The new class (to be placed in package
> >>>>>>>>>>   com.vividsolutions.jump.workbench.ui.renderer) is a drop-in
> >>>>>>>>>>   replacement for the default ThreadQueue in RenderingManager.
> >>>>>>>>>>   Not for the ThreadQueue that handles the DB/WMS layers.
> >>>>>>>>>>
> >>>>>>>>>>   Because Jon limited the number of parallel threads in default
> >>>>>>>>>>   queue to 1 I see no reason why to fork a new thread for each
> >>>>>>>>>>   Runnable it processes. Thread creation/shutdown is fairly
> >>>>>>>>>>   expensive. Instead a single background thread is started
> >>>>>>>>>>   which processes the Runnables one by one. If the thread
> >>>>>>>>>>   is idle for 30 secs it shuts itself down. If you have a lot
> >>>>>>>>>>   of (non-WMS/BB) layers this should improve performance
> >>>>>>>>>>   and save some resources. The processing itself is done
> >>>>>>>>>>   with a monitor (synchronized/wait/notify) so there is no
> >>>>>>>>>>   busy wait any more.
> >>>>>>>>>>
> >>>>>>>>>>   The DB/WMS ThreadQueue (real parallel threads) is left untouched
> >>>>>>>>>>   for the moment. Depending on my personal schedule I will send
> >>>>>>>>>>   a patch against this one too. Preliminary code with thread 
> >>>>>>>>>> pooling
> >>>>>>>>>>   exists but it needs a bit more testing.
> >>>>>>>>>>
> >>>>>>>>>>   Find attached the new class and patches against RenderingManager 
> >>>>>>>>>> and
> >>>>>>>>>>   the old ThreadQueue to bring it to work.
> >>>>>>>>>>
> >>>>>>>>>>   Comments are very welcome. :-)
> >>>>>>>>>>
> >>>>>>>>>>   Kind regrads,
> >>>>>>>>>>     Sascha
> >>>>>>>>>>
> >>>>>>>>>>   [1] com.vividsolutions.jump.workbench.ui.renderer.ThreadQueue
> >>>>>>>>>>   [2]
> >>>>>>>>>>   
> >>>>>>>>>> http://sourceforge.net/mailarchive/message.php?msg_name=4653389E.6000706%40intevation.de
> >>>>>>>>>>   [3] 
> >>>>>>>>>> com.vividsolutions.jump.workbench.ui.renderer.RenderingManager
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>------------------------------------------------------------------------
> >>>>>>>>>>
> >>>>>>>>>>/*
> >>>>>>>>>>* The Unified Mapping Platform (JUMP) is an extensible, interactive 
> >>>>>>>>>>GUI
> >>>>>>>>>>* for visualizing and manipulating spatial features with geometry 
> >>>>>>>>>>and attributes.
> >>>>>>>>>>*
> >>>>>>>>>>* Copyright (C) 2003 Vivid Solutions
> >>>>>>>>>>* Copyright (C) 2007 Intevation GmbH
> >>>>>>>>>>*
> >>>>>>>>>>* This program is free software; you can redistribute it and/or
> >>>>>>>>>>* modify it under the terms of the GNU General Public License
> >>>>>>>>>>* as published by the Free Software Foundation; either version 2
> >>>>>>>>>>* of the License, or (at your option) any later version.
> >>>>>>>>>>*
> >>>>>>>>>>* This program is distributed in the hope that it will be useful,
> >>>>>>>>>>* but WITHOUT ANY WARRANTY; without even the implied warranty of
> >>>>>>>>>>* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >>>>>>>>>>* GNU General Public License for more details.
> >>>>>>>>>>*
> >>>>>>>>>>* You should have received a copy of the GNU General Public License
> >>>>>>>>>>* along with this program; if not, write to the Free Software
> >>>>>>>>>>* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
> >>>>>>>>>>02111-1307, USA.
> >>>>>>>>>>*
> >>>>>>>>>>* Suite #1A
> >>>>>>>>>>* 2328 Government Street
> >>>>>>>>>>* Victoria BC  V8T 5G5
> >>>>>>>>>>* Canada
> >>>>>>>>>>*
> >>>>>>>>>>* (250)385-6040
> >>>>>>>>>>* www.vividsolutions.com
> >>>>>>>>>>*/
> >>>>>>>>>>package com.vividsolutions.jump.workbench.ui.renderer;
> >>>>>>>>>>
> >>>>>>>>>>import java.util.LinkedList;
> >>>>>>>>>>import java.util.ArrayList;
> >>>>>>>>>>
> >>>>>>>>>>/**
> >>>>>>>>>>* This thread queue executes at maximum N Runnables in parallel
> >>>>>>>>>>* were N is a given number of worker threads that should be used.
> >>>>>>>>>>* If N threads are running and busy each further incoming
> >>>>>>>>>>* Runnable is queued until one of the threads has finished its 
> >>>>>>>>>>current job.
> >>>>>>>>>>* If a worker thread becomes idle (no more job in the queue)
> >>>>>>>>>>* it is hold alive for 5 seconds. If during this period of time
> >>>>>>>>>>* no new Runnable is enqueued the worker thread dies.
> >>>>>>>>>>*
> >>>>>>>>>>* @author Sascha L. Teichmann ([EMAIL PROTECTED])
> >>>>>>>>>>*/
> >>>>>>>>>>public class ThreadQueue
> >>>>>>>>>>{
> >>>>>>>>>>      /** The time a worker thread stays alive if idle */
> >>>>>>>>>>      public static final long WORKER_STAY_ALIVE_TIME = 5000L;
> >>>>>>>>>>
> >>>>>>>>>>      /**
> >>>>>>>>>>       * Worker thread. Fetches Runnable from the surrounding
> >>>>>>>>>>       * ThreadQueue instance.
> >>>>>>>>>>       */
> >>>>>>>>>>      protected class Worker
> >>>>>>>>>>      extends         Thread
> >>>>>>>>>>      {
> >>>>>>>>>>              public void run() {
> >>>>>>>>>>                      try {
> >>>>>>>>>>                              for (;;) {
> >>>>>>>>>>                                      Runnable runnable;
> >>>>>>>>>>
> >>>>>>>>>>                                      synchronized 
> >>>>>>>>>> (queuedRunnables) {
> >>>>>>>>>>                                              if 
> >>>>>>>>>> (queuedRunnables.isEmpty()) {
> >>>>>>>>>>                                                      
> >>>>>>>>>> ++waitingThreads;
> >>>>>>>>>>                                                      try {
> >>>>>>>>>>                                                              
> >>>>>>>>>> queuedRunnables.wait(WORKER_STAY_ALIVE_TIME);
> >>>>>>>>>>                                                      }
> >>>>>>>>>>                                                      catch 
> >>>>>>>>>> (InterruptedException ie) {
> >>>>>>>>>>                                                      }
> >>>>>>>>>>                                                      finally {
> >>>>>>>>>>                                                              
> >>>>>>>>>> --waitingThreads;
> >>>>>>>>>>                                                      }
> >>>>>>>>>>
> >>>>>>>>>>                                                      // if still 
> >>>>>>>>>> empty -> die!
> >>>>>>>>>>                                                      if 
> >>>>>>>>>> (queuedRunnables.isEmpty())
> >>>>>>>>>>                                                              break;
> >>>>>>>>>>                                              }
> >>>>>>>>>>                                              if (disposed)
> >>>>>>>>>>                                                      break;
> >>>>>>>>>>                                              runnable = 
> >>>>>>>>>> (Runnable)queuedRunnables.remove();
> >>>>>>>>>>                                      } // synchronized 
> >>>>>>>>>> queuedRunnables
> >>>>>>>>>>
> >>>>>>>>>>                                      try {
> >>>>>>>>>>                                              runnable.run();
> >>>>>>>>>>                                      }
> >>>>>>>>>>                                      catch (Exception e) {
> >>>>>>>>>>                                              e.printStackTrace();
> >>>>>>>>>>                                      }
> >>>>>>>>>>                              } // for (;;)
> >>>>>>>>>>                      }
> >>>>>>>>>>                      finally { // guarantee that counter goes down
> >>>>>>>>>>                              boolean allRunningThreadsFinished;
> >>>>>>>>>>                              synchronized (runningThreads) {
> >>>>>>>>>>                                      allRunningThreadsFinished = 
> >>>>>>>>>> --runningThreads[0] == 0;
> >>>>>>>>>>                              }
> >>>>>>>>>>                              if (allRunningThreadsFinished)
> >>>>>>>>>>                                      
> >>>>>>>>>> fireAllRunningThreadsFinished();
> >>>>>>>>>>                      }
> >>>>>>>>>>              }
> >>>>>>>>>>      } // class Worker
> >>>>>>>>>>
> >>>>>>>>>>      /**
> >>>>>>>>>>       * If the number of running threads goes down to zero
> >>>>>>>>>>       * implementations of this interface are able to be informed.
> >>>>>>>>>>       */
> >>>>>>>>>>      public interface Listener {
> >>>>>>>>>>              void allRunningThreadsFinished();
> >>>>>>>>>>      } // interface Listener
> >>>>>>>>>>
> >>>>>>>>>>      /** Number of running threads */
> >>>>>>>>>>      protected int [] runningThreads = new int[1];
> >>>>>>>>>>
> >>>>>>>>>>      /** max. Number of threads running parallel */
> >>>>>>>>>>      protected int maxRunningThreads;
> >>>>>>>>>>
> >>>>>>>>>>      /** Number of threads that are currently idle */
> >>>>>>>>>>      protected int waitingThreads;
> >>>>>>>>>>
> >>>>>>>>>>      /** The queue of Runnables jobs waiting to be run */
> >>>>>>>>>>      protected LinkedList queuedRunnables;
> >>>>>>>>>>
> >>>>>>>>>>      /** Singals that the ThreadQueue is going to quit */
> >>>>>>>>>>      protected boolean disposed;
> >>>>>>>>>>
> >>>>>>>>>>      /** List of Listeners */
> >>>>>>>>>>      protected ArrayList listeners = new ArrayList();
> >>>>>>>>>>
> >>>>>>>>>>      /**
> >>>>>>>>>>       * Creates a ThreadQueue with one worker thread.
> >>>>>>>>>>       */
> >>>>>>>>>>      public ThreadQueue() {
> >>>>>>>>>>              this(1);
> >>>>>>>>>>      }
> >>>>>>>>>>
> >>>>>>>>>>      /** Creates a ThreadQueue with a given number of worker 
> >>>>>>>>>> threads.
> >>>>>>>>>>       * @param maxRunningThreads the max. number of threads to be 
> >>>>>>>>>> run parallel.
> >>>>>>>>>>       */
> >>>>>>>>>>      public ThreadQueue(int maxRunningThreads) {
> >>>>>>>>>>              this.maxRunningThreads = Math.max(1, 
> >>>>>>>>>> maxRunningThreads);
> >>>>>>>>>>              queuedRunnables = new LinkedList();
> >>>>>>>>>>      }
> >>>>>>>>>>
> >>>>>>>>>>      /**
> >>>>>>>>>>       * Adds a Listener to this ThreadQueue.
> >>>>>>>>>>       * @param listener the listener to add.
> >>>>>>>>>>       */
> >>>>>>>>>>      public synchronized void add(Listener listener) {
> >>>>>>>>>>              if (listener != null)
> >>>>>>>>>>                      listeners.add(listener);
> >>>>>>>>>>      }
> >>>>>>>>>>
> >>>>>>>>>>      /**
> >>>>>>>>>>       * Removes a Listener from this ThreadQueue.
> >>>>>>>>>>       * @param listener the listener to be removed.
> >>>>>>>>>>       */
> >>>>>>>>>>      public synchronized void remove(Listener listener) {
> >>>>>>>>>>              if (listener != null)
> >>>>>>>>>>                      listeners.add(listener);
> >>>>>>>>>>      }
> >>>>>>>>>>
> >>>>>>>>>>      /**
> >>>>>>>>>>       * Informs Listeners of the fact that the number of running 
> >>>>>>>>>> threads
> >>>>>>>>>>       * went to zero.
> >>>>>>>>>>       */
> >>>>>>>>>>      protected void fireAllRunningThreadsFinished() {
> >>>>>>>>>>              ArrayList copy;
> >>>>>>>>>>              synchronized (this) { copy = new 
> >>>>>>>>>> ArrayList(listeners); }
> >>>>>>>>>>              for (int i = copy.size()-1; i >= 0; --i)
> >>>>>>>>>>                      
> >>>>>>>>>> ((Listener)copy.get(i)).allRunningThreadsFinished();
> >>>>>>>>>>      }
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>      /**
> >>>>>>>>>>       * The number of currently running worker threads.
> >>>>>>>>>>       * @return number of currently running worker threads.
> >>>>>>>>>>       */
> >>>>>>>>>>      public int runningThreads() {
> >>>>>>>>>>              synchronized (runningThreads) {
> >>>>>>>>>>                      return runningThreads[0];
> >>>>>>>>>>              }
> >>>>>>>>>>      }
> >>>>>>>>>>
> >>>>>>>>>>      /**
> >>>>>>>>>>       * The number of currently waiting Runnables.
> >>>>>>>>>>       * @return number of currently waiting Runnables.
> >>>>>>>>>>       */
> >>>>>>>>>>      public int waitingRunnables() {
> >>>>>>>>>>              synchronized (runningThreads) {
> >>>>>>>>>>                      return queuedRunnables.size();
> >>>>>>>>>>              }
> >>>>>>>>>>      }
> >>>>>>>>>>
> >>>>>>>>>>      /**
> >>>>>>>>>>       * The number of currently idle worker threads.
> >>>>>>>>>>       * @return number of currently idle worker threads.
> >>>>>>>>>>       */
> >>>>>>>>>>      public int waitingThreads() {
> >>>>>>>>>>              synchronized (queuedRunnables) {
> >>>>>>>>>>                      return waitingThreads;
> >>>>>>>>>>              }
> >>>>>>>>>>      }
> >>>>>>>>>>
> >>>>>>>>>>      /**
> >>>>>>>>>>       * Adds a Runnables to the queue. It will be run in one
> >>>>>>>>>>       * of the worker threads.
> >>>>>>>>>>       * @param runnable The Runnables to add
> >>>>>>>>>>       */
> >>>>>>>>>>      public void add(Runnable runnable) {
> >>>>>>>>>>              int waiting;
> >>>>>>>>>>              synchronized (queuedRunnables) {
> >>>>>>>>>>                      if (disposed)
> >>>>>>>>>>                              return;
> >>>>>>>>>>                      waiting = waitingThreads;
> >>>>>>>>>>                      queuedRunnables.add(runnable);
> >>>>>>>>>>                      queuedRunnables.notify();
> >>>>>>>>>>              }  // synchronized (queuedRunnables)
> >>>>>>>>>>
> >>>>>>>>>>              synchronized (runningThreads) {
> >>>>>>>>>>
> >>>>>>>>>>                      // if waitingThreads == 1 then
> >>>>>>>>>>                      // the queuedRunnables.notify() should have 
> >>>>>>>>>> waked it up.
> >>>>>>>>>>
> >>>>>>>>>>                      if (waitingThreads < 2 && runningThreads[0] < 
> >>>>>>>>>> maxRunningThreads) {
> >>>>>>>>>>                              ++runningThreads[0];
> >>>>>>>>>>                              Worker w = new Worker();
> >>>>>>>>>>                              w.setDaemon(true);
> >>>>>>>>>>                              w.start();
> >>>>>>>>>>                      }
> >>>>>>>>>>              } // synchronized (runningThreads)
> >>>>>>>>>>      }
> >>>>>>>>>>
> >>>>>>>>>>      /**
> >>>>>>>>>>       * Empties the queue of waiting Runnables.
> >>>>>>>>>>       */
> >>>>>>>>>>      public void clear() {
> >>>>>>>>>>              synchronized (queuedRunnables) {
> >>>>>>>>>>                      queuedRunnables.clear();
> >>>>>>>>>>              }
> >>>>>>>>>>      }
> >>>>>>>>>>
> >>>>>>>>>>      /**
> >>>>>>>>>>       * Shuts down the ThreadQueue.
> >>>>>>>>>>       */
> >>>>>>>>>>      public void dispose() {
> >>>>>>>>>>              synchronized (queuedRunnables) {
> >>>>>>>>>>                      disposed = true;
> >>>>>>>>>>                      queuedRunnables.clear();
> >>>>>>>>>>                      // wakeup idle threads
> >>>>>>>>>>                      queuedRunnables.notifyAll();
> >>>>>>>>>>              }
> >>>>>>>>>>              synchronized (this) {
> >>>>>>>>>>                      listeners.clear();
> >>>>>>>>>>              }
> >>>>>>>>>>      }
> >>>>>>>>>>}
> >>>>>>>>>>// end of file
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>------------------------------------------------------------------------
> >>>>>>>>>>
> >>>>>>>>>>-------------------------------------------------------------------------
> >>>>>>>>>>This SF.net email is sponsored by DB2 Express
> >>>>>>>>>>Download DB2 Express C - the FREE version of DB2 express and take
> >>>>>>>>>>control of your XML. No limits. Just data. Click to get it now.
> >>>>>>>>>>http://sourceforge.net/powerbar/db2/
> >>>>>>>>>>
> >>>>>>>>>>------------------------------------------------------------------------
> >>>>>>>>>>
> >>>>>>>>>>_______________________________________________
> >>>>>>>>>>Jump-pilot-devel mailing list
> >>>>>>>>>>Jump-pilot-devel@lists.sourceforge.net
> >>>>>>>>>>https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>-------------------------------------------------------------------------
> >>>>This SF.net email is sponsored by DB2 Express
> >>>>Download DB2 Express C - the FREE version of DB2 express and take
> >>>>control of your XML. No limits. Just data. Click to get it now.
> >>>>http://sourceforge.net/powerbar/db2/
> >>>>_______________________________________________
> >>>>Jump-pilot-devel mailing list
> >>>>Jump-pilot-devel@lists.sourceforge.net
> >>>>https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel
> >>>>
> >>>>
> >>>>
> >>>>
> >>>-------------------------------------------------------------------------
> >>>This SF.net email is sponsored by DB2 Express
> >>>Download DB2 Express C - the FREE version of DB2 express and take
> >>>control of your XML. No limits. Just data. Click to get it now.
> >>>http://sourceforge.net/powerbar/db2/
> >>>_______________________________________________
> >>>Jump-pilot-devel mailing list
> >>>Jump-pilot-devel@lists.sourceforge.net
> >>>https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel
> >>>
> >>>
> >>-------------------------------------------------------------------------
> >>This SF.net email is sponsored by DB2 Express
> >>Download DB2 Express C - the FREE version of DB2 express and take
> >>control of your XML. No limits. Just data. Click to get it now.
> >>http://sourceforge.net/powerbar/db2/
> >>_______________________________________________
> >>Jump-pilot-devel mailing list
> >>Jump-pilot-devel@lists.sourceforge.net
> >>https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel
> >>
> >>
> >>
> >>
> >
> >-------------------------------------------------------------------------
> >This SF.net email is sponsored by DB2 Express
> >Download DB2 Express C - the FREE version of DB2 express and take
> >control of your XML. No limits. Just data. Click to get it now.
> >http://sourceforge.net/powerbar/db2/
> >_______________________________________________
> >Jump-pilot-devel mailing list
> >Jump-pilot-devel@lists.sourceforge.net
> >https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel
> >
> >
> >
> >
>
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by DB2 Express
> Download DB2 Express C - the FREE version of DB2 express and take
> control of your XML. No limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> _______________________________________________
> Jump-pilot-devel mailing list
> Jump-pilot-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel
>


-- 
http://amusingprogrammer.blogspot.com/

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to