/** * If the thread is currently active, calls {@link #executionCancelled()} to notify children. If * not active, removes the thread from the queue so it won't become active. */ public final void cancel() { boolean dependentThreads = false; synchronized (LOCK) { dependentThreads = checkQueuedThreadDependOnCurrentThread(); } if (dependentThreads) { if (ConfirmDialog.OK_OPTION != SwingTools.showConfirmDialog( "cancel_pg_with_dependencies", ConfirmDialog.OK_CANCEL_OPTION)) { return; } else { synchronized (LOCK) { removeQueuedThreadsWithDependency(getID()); } } } synchronized (LOCK) { cancelled = true; if (started) { executionCancelled(); currentThreads.remove(this); } else { // cancel and not started? Can only be in queue queuedThreads.remove(this); } } taskCancelled(this); }
/** * Removes all queued threads that depend on the progress threads with the provided IDs. Also all * thread that depend on the threads that have been removed are removed recursively. * * <p><strong>ATTENTION: Make sure this is only called from inside a synchronized block!</strong> * * @param ids the progress thread IDs the queued progress threads should be checked for */ private static final void removeQueuedThreadsWithDependency(String... ids) { Iterator<ProgressThread> iterator = queuedThreads.iterator(); // iterator over queued threads and remove the remove the ones that depend on one of the // provided IDs Set<String> cancelledThreads = new HashSet<>(); while (iterator.hasNext()) { ProgressThread pg = iterator.next(); if (!Collections.disjoint(Arrays.asList(ids), pg.getDependencies())) { iterator.remove(); cancelledThreads.add(pg.getID()); } } // also remove all the ones depending on the ones that have been cancelled. if (!cancelledThreads.isEmpty()) { removeQueuedThreadsWithDependency( cancelledThreads.toArray(new String[cancelledThreads.size()])); } }