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