Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing ExecutorService and ProgressMonitor in a Thread Safe Manner
    primarykey
    data
    text
    <p>I first define the ProgressMonitor:</p> <pre><code>progressMonitor = new ProgressMonitor(parent, "Starting processing ...", "", 0, maxNumberProcesses+1); progressMonitor.setProgress(0); </code></pre> <p>and on the same thread use an ExecutorService and invokeAll() to process a list of Callables:</p> <pre><code>ExecutorService execService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); // use all available processors at startup execService.invokeAll(callables); // wait for all tasks to complete execService.shutdownNow(); // free thread pool resources </code></pre> <p>Each Callable is of the form:</p> <pre><code>class Callable implements Callable&lt;List&lt;String&gt;&gt; { public List&lt;String&gt; call() { List&lt;String&gt; files = doSomeStuff(); progressBarUpdate(); return files; } } </code></pre> <p>ie; each Callable calls progressBarUpdate():</p> <pre><code>private void progressBarUpdate() { if (progressMonitor != null) { Lock lock = new ReentrantLock(); lock.lock(); try { progressMonitor.increment(); } finally { lock.unlock(); // release lock } } } </code></pre> <p>Each doSomeStuff() has its own exception handling and if an error occurs or an exception is thrown then a null value is returned. This is why the return type is a List, and returns null in such cases. There is no crossover between the Callables and the List of files they return, they all maintain there own list of files.</p> <p>I find that it works fine but occasionally it throws an InterruptedException of the form:</p> <pre><code>Disposal was interrupted: java.lang.InterruptedException at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:503) at java.awt.EventQueue.invokeAndWait(EventQueue.java:1263) at java.awt.Window.doDispose(Window.java:1209) at java.awt.Dialog.doDispose(Dialog.java:1196) at java.awt.Window.dispose(Window.java:1147) at javax.swing.ProgressMonitor.close(ProgressMonitor.java:311) at javax.swing.ProgressMonitor.setProgress(ProgressMonitor.java:264) </code></pre> <p>showing that setProgress() calls close() when the monitor max is reached:</p> <pre><code>public void setProgress(int nv) { if (nv &gt;= max) { close(); } ... </code></pre> <p>and close() contains numerous other non-thread safe calls.</p> <p>I've modified my code so that the condition nv>=max is not satisfied and I explicitly call ProgressMonitor.close() after invokeAll(), but I'm still not convinced that such an approach is completely thread safe.</p> <p>Has anyone else encountered this situation and found a rock-solid solution?</p> <p>Thanks</p> <p>Graham</p> <p>PS. Note that ProgressMonitor is not a swing widget but does encapsulate Swing components. As a result I ensure that ProgressMonitor does not run on the EDT.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload