View Javadoc
1   package org.apache.maven.surefire.junitcore.pc;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.surefire.report.ConsoleStream;
23  
24  import java.util.Collection;
25  import java.util.concurrent.ExecutorService;
26  import java.util.concurrent.Future;
27  import java.util.concurrent.ThreadPoolExecutor;
28  import java.util.concurrent.TimeUnit;
29  
30  /**
31   * Abstract parallel scheduling strategy in private package.
32   * The remaining abstract methods have to be implemented differently
33   * depending if the thread pool is shared with other strategies or not.
34   *
35   * @author Tibor Digana (tibor17)
36   * @see SchedulingStrategy
37   * @see SharedThreadPoolStrategy
38   * @see NonSharedThreadPoolStrategy
39   * @since 2.16
40   */
41  abstract class AbstractThreadPoolStrategy
42      extends SchedulingStrategy
43  {
44      private final ExecutorService threadPool;
45  
46      private final Collection<Future<?>> futureResults;
47  
48      private volatile boolean isDestroyed;
49  
50      AbstractThreadPoolStrategy( ConsoleStream logger, ExecutorService threadPool )
51      {
52          this( logger, threadPool, null );
53      }
54  
55      AbstractThreadPoolStrategy( ConsoleStream logger, ExecutorService threadPool, Collection<Future<?>> futureResults )
56      {
57          super( logger );
58          this.threadPool = threadPool;
59          this.futureResults = futureResults;
60      }
61  
62      protected final ExecutorService getThreadPool()
63      {
64          return threadPool;
65      }
66  
67      protected final Collection<Future<?>> getFutureResults()
68      {
69          return futureResults;
70      }
71  
72      @Override
73      public void schedule( Runnable task )
74      {
75          if ( canSchedule() )
76          {
77              Future<?> futureResult = threadPool.submit( task );
78              if ( futureResults != null )
79              {
80                  futureResults.add( futureResult );
81              }
82          }
83      }
84  
85      @Override
86      protected boolean stop()
87      {
88          boolean wasRunning = disable();
89          if ( threadPool.isShutdown() )
90          {
91              wasRunning = false;
92          }
93          else
94          {
95              threadPool.shutdown();
96          }
97          return wasRunning;
98      }
99  
100     @Override
101     protected boolean stopNow()
102     {
103         boolean wasRunning = disable();
104         if ( threadPool.isShutdown() )
105         {
106             wasRunning = false;
107         }
108         else
109         {
110             threadPool.shutdownNow();
111         }
112         return wasRunning;
113     }
114 
115     /**
116      * @see Scheduler.ShutdownHandler
117      */
118     @Override
119     protected void setDefaultShutdownHandler( Scheduler.ShutdownHandler handler )
120     {
121         if ( threadPool instanceof ThreadPoolExecutor )
122         {
123             ThreadPoolExecutor pool = (ThreadPoolExecutor) threadPool;
124             handler.setRejectedExecutionHandler( pool.getRejectedExecutionHandler() );
125             pool.setRejectedExecutionHandler( handler );
126         }
127     }
128 
129     public boolean destroy()
130     {
131         try
132         {
133             if ( !isDestroyed )//just an optimization
134             {
135                 disable();
136                 threadPool.shutdown();
137                 this.isDestroyed |= threadPool.awaitTermination( Long.MAX_VALUE, TimeUnit.NANOSECONDS );
138             }
139             return isDestroyed;
140         }
141         catch ( InterruptedException e )
142         {
143             return false;
144         }
145     }
146 }