001package com.pi4j.concurrent;
002
003/*
004 * #%L
005 * **********************************************************************
006 * ORGANIZATION  :  Pi4J
007 * PROJECT       :  Pi4J :: Java Library (Core)
008 * FILENAME      :  DefaultExecutorServiceFactory.java  
009 * 
010 * This file is part of the Pi4J project. More information about 
011 * this project can be found here:  http://www.pi4j.com/
012 * **********************************************************************
013 * %%
014 * Copyright (C) 2012 - 2013 Pi4J
015 * %%
016 * Licensed under the Apache License, Version 2.0 (the "License");
017 * you may not use this file except in compliance with the License.
018 * You may obtain a copy of the License at
019 * 
020 *      http://www.apache.org/licenses/LICENSE-2.0
021 * 
022 * Unless required by applicable law or agreed to in writing, software
023 * distributed under the License is distributed on an "AS IS" BASIS,
024 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
025 * See the License for the specific language governing permissions and
026 * limitations under the License.
027 * #L%
028 */
029
030
031import java.util.ArrayList;
032import java.util.List;
033import java.util.concurrent.ExecutorService;
034import java.util.concurrent.Executors;
035import java.util.concurrent.ScheduledExecutorService;
036import java.util.concurrent.ThreadFactory;
037
038public class DefaultExecutorServiceFactory implements ExecutorServiceFactory {
039    
040    public static int MAX_THREADS_IN_POOL = 25;
041    private static List<ExecutorService> singleThreadExecutorServices  = new ArrayList<ExecutorService>();
042    private static ScheduledExecutorService scheduledExecutorService = null;
043    private static ScheduledExecutorServiceWrapper executorServiceWrapper = null;
044    
045    /**
046     * return an instance to the thread factory used to create new executor services
047     */
048    private ThreadFactory getThreadFactory(){
049        return Executors.defaultThreadFactory();
050    }
051    
052    /**
053     * return an instance to the scheduled executor service (wrapper)
054     */
055    public ScheduledExecutorService getScheduledExecutorService(){
056        if(scheduledExecutorService == null){
057            scheduledExecutorService = Executors.newScheduledThreadPool(MAX_THREADS_IN_POOL, getThreadFactory());
058            executorServiceWrapper = new ScheduledExecutorServiceWrapper(scheduledExecutorService);
059        }
060        
061        // we return the protected wrapper to prevent any consumers from 
062        // being able to shutdown the scheduled executor service
063        return executorServiceWrapper;
064    }
065    
066    /**
067     * return a new instance of a single thread executor service
068     */
069    public ExecutorService newSingleThreadExecutorService(){
070        
071        // create new single thread executor
072        ExecutorService singleThreadExecutorService = Executors.newSingleThreadExecutor(getThreadFactory());
073
074        // add new instance to managed collection
075        singleThreadExecutorServices.add(singleThreadExecutorService);
076        
077        // return the new instance
078        return singleThreadExecutorService;
079    }
080    
081    /**
082     * shutdown executor threads
083     */
084    public void shutdown(){
085        
086        // shutdown each single thread executor in the managed collection
087        for(ExecutorService singleThreadExecutorService : singleThreadExecutorServices){
088            if(singleThreadExecutorService != null){
089                if(!singleThreadExecutorService.isShutdown()){
090                    // this is a forceful shutdown; 
091                    // don't wait for the active tasks to complete
092                    singleThreadExecutorService.shutdownNow();
093                }
094            }
095        }
096        
097        // shutdown scheduled executor instance 
098        if(scheduledExecutorService != null){
099            if(!scheduledExecutorService.isShutdown()){
100                // this is a forceful shutdown; 
101                // don't wait for the scheduled tasks to complete
102                scheduledExecutorService.shutdownNow();
103            }
104        }
105    }
106}