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