/** * Copyright (C) 2001-2017 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * 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 * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.gui.tools; import com.rapidminer.tools.I18N; import com.rapidminer.tools.LogService; import java.util.logging.Level; /** * A queue of runnables in which only execution of the last is relevant. Older runnables become * obsolete as soon as a new is inserted. * * @author Simon Fischer * */ public class UpdateQueue extends Thread { private Runnable pending; public UpdateQueue(String name) { super("UpdateQueue-" + name); setDaemon(true); } private Object lock = new Object(); private boolean shutdownRequested = false; /** * Queues runnable for execution. Will be executed as soon as the current runnable has * terminated. If there is no current executable, will be executed immediately (in the thread * created by this instance). If this method is called again before the current runnable is * executed, runnable will be discarded in favor of the new. */ public void execute(Runnable runnable) { synchronized (lock) { pending = runnable; lock.notifyAll(); } } /** * Executes the given progress thread and waits for it, so only one will be enqueued at a time. * (The calling thread will *not* wait, only the queue waits! */ public void executeBackgroundJob(final ProgressThread progressThread) { execute(new Runnable() { @Override public void run() { progressThread.startAndWait(); } }); } @Override public void run() { while (!shutdownRequested) { final Runnable target; synchronized (lock) { target = pending; pending = null; } if (target != null) { try { target.run(); } catch (Exception e) { // LogService.getRoot().log(Level.WARNING, // "Error executing task in "+getName()+": "+e, e); LogService.getRoot().log( Level.WARNING, I18N.getMessage(LogService.getRoot().getResourceBundle(), "com.rapidminer.gui.tools.UpdateQueue.error_executing_task", getName(), e), e); } } synchronized (lock) { if (pending == null) { try { lock.wait(); } catch (InterruptedException e) { } } } } } public void shutdown() { synchronized (lock) { pending = null; shutdownRequested = true; lock.notifyAll(); } } }