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 java.util.concurrent.atomic.AtomicBoolean;
23  
24  /**
25   * Specifies the strategy of scheduling whether sequential, or parallel.
26   * The strategy may use a thread pool <em>shared</em> with other strategies.
27   * <p/>
28   * One instance of strategy can be used just by one {@link Scheduler}.
29   * <p/>
30   * The strategy is scheduling tasks in {@link #schedule(Runnable)} and awaiting them
31   * completed in {@link #finished()}. Both methods should be used in one thread.
32   *
33   * @author Tibor Digana (tibor17)
34   * @since 2.16
35   */
36  public abstract class SchedulingStrategy
37      implements Destroyable
38  {
39  
40      private final AtomicBoolean canSchedule = new AtomicBoolean( true );
41  
42      /**
43       * Schedules tasks if {@link #canSchedule()}.
44       *
45       * @param task runnable to schedule in a thread pool or invoke
46       * @throws RejectedExecutionException if <tt>task</tt>
47       *                                    cannot be scheduled for execution
48       * @throws NullPointerException       if <tt>task</tt> is <tt>null</tt>
49       * @see RunnerScheduler#schedule(Runnable)
50       * @see java.util.concurrent.Executor#execute(Runnable)
51       */
52      protected abstract void schedule( Runnable task );
53  
54      /**
55       * Waiting for scheduled tasks to finish.
56       * New tasks will not be scheduled by calling this method.
57       *
58       * @return <tt>true</tt> if successfully stopped the scheduler, else
59       *         <tt>false</tt> if already stopped (a <em>shared</em> thread
60       *         pool was shutdown externally).
61       * @throws InterruptedException if interrupted while waiting
62       *                              for scheduled tasks to finish
63       * @see RunnerScheduler#finished()
64       */
65      protected abstract boolean finished()
66          throws InterruptedException;
67  
68      /**
69       * Stops scheduling new tasks (e.g. by {@link java.util.concurrent.ExecutorService#shutdown()}
70       * on a private thread pool which cannot be <em>shared</em> with other strategy).
71       *
72       * @return <tt>true</tt> if successfully stopped the scheduler, else
73       *         <tt>false</tt> if already stopped (a <em>shared</em> thread
74       *         pool was shutdown externally).
75       * @see java.util.concurrent.ExecutorService#shutdown()
76       */
77      protected abstract boolean stop();
78  
79      /**
80       * Stops scheduling new tasks and <em>interrupts</em> running tasks
81       * (e.g. by {@link java.util.concurrent.ExecutorService#shutdownNow()} on a private thread pool
82       * which cannot be <em>shared</em> with other strategy).
83       * <p/>
84       * This method calls {@link #stop()} by default.
85       *
86       * @return <tt>true</tt> if successfully stopped the scheduler, else
87       *         <tt>false</tt> if already stopped (a <em>shared</em> thread
88       *         pool was shutdown externally).
89       * @see java.util.concurrent.ExecutorService#shutdownNow()
90       */
91      protected boolean stopNow()
92      {
93          return stop();
94      }
95  
96      /**
97       * Persistently disables this strategy. Atomically ignores {@link Balancer} to acquire a new permit.<p/>
98       * The method {@link #canSchedule()} atomically returns {@code false}.
99       * @return {@code true} if {@link #canSchedule()} has return {@code true} on the beginning of this method call.
100      */
101     protected boolean disable()
102     {
103         return canSchedule.getAndSet( false );
104     }
105 
106     protected void setDefaultShutdownHandler( Scheduler.ShutdownHandler handler )
107     {
108     }
109 
110     /**
111      * @return <tt>true</tt> if a thread pool associated with this strategy
112      *         can be shared with other strategies.
113      */
114     protected abstract boolean hasSharedThreadPool();
115 
116     /**
117      * @return <tt>true</tt> unless stopped, finished or disabled.
118      */
119     protected boolean canSchedule()
120     {
121         return canSchedule.get();
122     }
123 
124     protected void logQuietly( Throwable t )
125     {
126         t.printStackTrace( System.out );
127     }
128 }