001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.system.thread;
020
021import java.util.concurrent.FutureTask;
022
023/**
024 * Single instance processor.<br>
025 * It allows to run processes on a thread and verify the constraint that only one single instance of
026 * a specific process can be queued at a given time.
027 */
028public class InstanceProcessor extends Processor
029{
030    /**
031     * Create an InstanceProcessor
032     */
033    public InstanceProcessor(int maxWaiting, int priority)
034    {
035        super(maxWaiting, 1, priority);
036
037        setThreadName("InstanceProcessor");
038    }
039
040    /**
041     * Create an InstanceProcessor
042     */
043    public InstanceProcessor(int priority)
044    {
045        this(-1, priority);
046    }
047
048    /**
049     * Create an InstanceProcessor
050     */
051    public InstanceProcessor()
052    {
053        this(Processor.NORM_PRIORITY);
054    }
055
056    /**
057     * Try to submit the specified task for execution and returns a Future representing that task.<br>
058     * The Future's <tt>get</tt> method will return <tt>null</tt> upon <em>successful</em>
059     * completion.<br>
060     * Returns a <code>null</code> Future object if processor has already this task pending in queue
061     * (in this case the new task is simply ignored)..
062     */
063    @Override
064    protected synchronized <T> FutureTask<T> submit(FutureTaskAdapter<T> task)
065    {
066        // task already present in queue --> return null (mean the task was ignored)
067        if ((task.runnable != null) && hasWaitingTasks(task.runnable))
068            return null;
069        if ((task.callable != null) && hasWaitingTasks(task.callable))
070            return null;
071
072        // add task only if not already present in queue
073        return super.submit(task);
074    }
075}