Hi Sascha,

  I do not see the difference.  It seems to me that when a task is
finished, the runningThreads count is decremented as in:

                try {
                    runnable.run();
                } finally {
                    setRunningThreads(getRunningThreads() - 1);
                    processQueue();
                }

So it would seem to me that when the count reaches zero that there are
no more jobs.

regards,
Larry

On 5/30/07, Sascha L. Teichmann <[EMAIL PROTECTED]> wrote:
> Hi Larry,
>
> The method is named runningThreads(). This was my
> mistake. I will add add get getRunningThreads() to
> reestablish compatibility. Thanks for this hint.
>
> BTW: You're code:
>
> while (threadQueue.getRunningThreads() > 0) Thread.sleep(200);
>
> tests if there are running _threads_ left. This do not tell
> you if there are _jobs_ to to! What you really want to know
> is when the last job is done. See the difference?
>
> The new RenderingManager will have a new method to archive
> this. It will switch the thread queue to single threaded mode
> and enqueues a special Runnable at the end. Then the calling
> thread is lock with a monitor. If the special Runnable is
> executed the monitor is unlocked and the calling thread continues.
> This is what you want.
>
> Switching to single thread mode has the advantage to keep
> the correct z order of the layers. This is essential for
> printing because you don't want to have any internal repaint()
> operations. This causes overdraw. If you render to bitmap this
> might be okay, but if you want to send the vector information
> to the Graphics2D of the output driver this is not a good idea.
>
> Kind regards,
>   Sascha
>
>
> Larry Becker schrieb:
> > 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
> >>
> >
> >
>
> -------------------------------------------------------------------------
> 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