001    package org.apache.maven.lifecycle.internal;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *  http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.codehaus.plexus.component.annotations.Component;
023    import org.codehaus.plexus.component.annotations.Requirement;
024    import org.codehaus.plexus.logging.Logger;
025    
026    import java.util.concurrent.ExecutorService;
027    import java.util.concurrent.Executors;
028    
029    /**
030     * @since 3.0
031     */
032    @Component( role = ThreadConfigurationService.class )
033    public class ThreadConfigurationService
034    {
035        @Requirement
036        private Logger logger;
037    
038        private final int cpuCores;
039    
040    
041        public ThreadConfigurationService()
042        {
043            cpuCores = Runtime.getRuntime().availableProcessors();
044        }
045    
046        public ThreadConfigurationService( Logger logger, int cpuCores )
047        {
048            this.logger = logger;
049            this.cpuCores = cpuCores;
050        }
051    
052    
053        public ExecutorService getExecutorService( String threadCountConfiguration, boolean perCoreThreadCount,
054                                                   int largestBuildListSize )
055        {
056            Integer threadCount = getThreadCount( threadCountConfiguration, perCoreThreadCount, largestBuildListSize );
057            return getExecutorService( threadCount );
058    
059    
060        }
061    
062        private ExecutorService getExecutorService( Integer threadCount )
063        {
064            if ( threadCount == null )
065            {
066                logger.info( "Building with unlimited threads" );
067                return Executors.newCachedThreadPool();
068            }
069    
070            logger.info( "Building with " + threadCount + " threads" );
071            return Executors.newFixedThreadPool( threadCount );
072        }
073    
074        /**
075         * Returns the thread count to use or null for unlimited threads.
076         *
077         * @param threadCountConfiguration The property passed from the command line.
078         * @param perCoreThreadCount       Indicates if the threa count should be scaled per cpu core.
079         * @param largestBuildListSize     the size of the largest module list (the number of modules)
080         * @return The number of threads to use or null if unlimited
081         */
082    
083        Integer getThreadCount( String threadCountConfiguration, boolean perCoreThreadCount, int largestBuildListSize )
084        {
085            // Default to a value that is not larger than what we can use ;)
086            float threadCount = Math.min( cpuCores, largestBuildListSize );
087            if ( threadCountConfiguration != null )
088            {
089                try
090                {
091                    threadCount = Float.parseFloat( threadCountConfiguration );
092                }
093                catch ( NumberFormatException e )
094                {
095                    logger.warn(
096                        "Couldn't parse thread count, will default to " + threadCount + ": " + threadCountConfiguration );
097                }
098            }
099            if ( perCoreThreadCount )
100            {
101                threadCount = threadCount * cpuCores;
102            }
103    
104            final int endResult = Math.round( threadCount );
105            if ( logger.isDebugEnabled() )
106            {
107                logger.debug( "Thread pool size: " + endResult );
108            }
109            return endResult;
110        }
111    }