>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