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        @SuppressWarnings( { "UnusedDeclaration" } )
042        public ThreadConfigurationService()
043        {
044            cpuCores = Runtime.getRuntime().availableProcessors();
045        }
046    
047        public ThreadConfigurationService( Logger logger, int cpuCores )
048        {
049            this.logger = logger;
050            this.cpuCores = cpuCores;
051        }
052    
053    
054        public ExecutorService getExecutorService( String threadCountConfiguration, boolean perCoreThreadCount,
055                                                   int largestBuildListSize )
056        {
057            Integer threadCount = getThreadCount( threadCountConfiguration, perCoreThreadCount, largestBuildListSize );
058            return getExecutorService( threadCount );
059    
060    
061        }
062    
063        private ExecutorService getExecutorService( Integer threadCount )
064        {
065            if ( threadCount == null )
066            {
067                logger.info( "Building with unlimited threads" );
068                return Executors.newCachedThreadPool();
069            }
070    
071            logger.info( "Building with " + threadCount + " threads" );
072            return Executors.newFixedThreadPool( threadCount );
073        }
074    
075        /**
076         * Returns the thread count to use or null for unlimited threads.
077         *
078         * @param threadCountConfiguration The property passed from the command line.
079         * @param perCoreThreadCount       Indicates if the threa count should be scaled per cpu core.
080         * @param largestBuildListSize     the size of the largest module list (the number of modules)
081         * @return The number of threads to use or null if unlimited
082         */
083    
084        Integer getThreadCount( String threadCountConfiguration, boolean perCoreThreadCount, int largestBuildListSize )
085        {
086            // Default to a value that is not larger than what we can use ;)
087            float threadCount = Math.min( cpuCores, largestBuildListSize );
088            if ( threadCountConfiguration != null )
089            {
090                try
091                {
092                    threadCount = Float.parseFloat( threadCountConfiguration );
093                }
094                catch ( NumberFormatException e )
095                {
096                    logger.warn(
097                        "Couldn't parse thread count, will default to " + threadCount + ": " + threadCountConfiguration );
098                }
099            }
100            if ( perCoreThreadCount )
101            {
102                threadCount = threadCount * cpuCores;
103            }
104    
105            final int endResult = Math.round( threadCount );
106            if ( logger.isDebugEnabled() )
107            {
108                logger.debug( "Thread pool size: " + endResult );
109            }
110            return endResult;
111        }
112    }