/* * JAME 6.2.1 * http://jame.sourceforge.net * * Copyright 2001, 2016 Andrea Medeghini * * This file is part of JAME. * * JAME is an application for creating fractals and other graphics artifacts. * * JAME 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 3 of the License, or * (at your option) any later version. * * JAME 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 JAME. If not, see <http://www.gnu.org/licenses/>. * */ package net.sf.jame.core.util; import java.util.LinkedList; import java.util.List; import java.util.concurrent.ThreadFactory; /** * @author Andrea Medeghini */ public class Worker { private final List<Runnable> tasks = new LinkedList<Runnable>(); private ThreadFactory factory; private volatile Thread thread; private volatile boolean running; private volatile Runnable runnable; /** * @param factory */ public Worker(final ThreadFactory factory) { this.factory = factory; } /** * @param runnable * @return */ protected Thread createThread(Runnable runnable) { return factory.newThread(runnable); } /** * */ public void stop() { running = false; if (thread != null) { abortTasks(); try { thread.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } thread = null; } } /** * */ public void start() { if (thread == null) { thread = createThread(new WorkerRunnable()); running = true; thread.start(); } } /** * */ public void waitTasks() { synchronized (tasks) { while ((runnable != null) || (tasks.size() > 0)) { try { tasks.wait(); } catch (InterruptedException e) { } } } } /** * */ public void terminateTasks() { synchronized (tasks) { while ((runnable != null) || (tasks.size() > 0)) { if (thread != null) { thread.interrupt(); } try { tasks.wait(1000); } catch (InterruptedException e) { } } } } /** * */ public void abortTasks() { synchronized (tasks) { tasks.clear(); if (thread != null) { thread.interrupt(); } } } /** * */ public void resumeTasks() { synchronized (tasks) { tasks.notify(); } } /** * */ public void clearTasks() { synchronized (tasks) { tasks.clear(); } } /** * @param task */ public void addTask(final Runnable task) { synchronized (tasks) { tasks.add(task); tasks.notify(); } } /** * @return */ public int tasksCount() { synchronized (tasks) { return tasks.size(); } } private class WorkerRunnable implements Runnable { /** * @see java.lang.Runnable#run() */ public void run() { try { while (running) { Thread.interrupted(); synchronized (tasks) { tasks.notifyAll(); try { while (!Thread.interrupted() && tasks.size() == 0) { tasks.wait(); } if (tasks.size() > 0) { runnable = tasks.remove(0); } } catch (final InterruptedException e) { Thread.currentThread().interrupt(); } } try { if (runnable != null) { runnable.run(); } } catch (Throwable e) { e.printStackTrace(); } finally { runnable = null; } } } finally { synchronized (tasks) { runnable = null; tasks.clear(); tasks.notifyAll(); } } } } }