1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.apache.maven.surefire.junitcore.pc; 20 21 import java.util.concurrent.atomic.AtomicBoolean; 22 23 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger; 24 25 /** 26 * Specifies the strategy of scheduling whether sequential, or parallel. 27 * The strategy may use a thread pool <b>shared</b> with other strategies. 28 * <br> 29 * One instance of strategy can be used just by one {@link Scheduler}. 30 * <br> 31 * The strategy is scheduling tasks in {@link #schedule(Runnable)} and awaiting them 32 * completed in {@link #finished()}. Both methods should be used in one thread. 33 * 34 * @author Tibor Digana (tibor17) 35 * @since 2.16 36 */ 37 public abstract class SchedulingStrategy implements Destroyable { 38 39 private final AtomicBoolean canSchedule = new AtomicBoolean(true); 40 41 private final ConsoleLogger logger; 42 43 protected SchedulingStrategy(ConsoleLogger logger) { 44 this.logger = logger; 45 } 46 47 /** 48 * Schedules tasks if {@link #canSchedule()}. 49 * 50 * @param task runnable to schedule in a thread pool or invoke 51 * @throws java.util.concurrent.RejectedExecutionException if <code>task</code> 52 * cannot be scheduled for execution 53 * @throws NullPointerException if <code>task</code> is <code>null</code> 54 * @see org.junit.runners.model.RunnerScheduler#schedule(Runnable) 55 * @see java.util.concurrent.Executor#execute(Runnable) 56 */ 57 protected abstract void schedule(Runnable task); 58 59 /** 60 * Waiting for scheduled tasks to finish. 61 * New tasks will not be scheduled by calling this method. 62 * 63 * @return {@code true} if successfully stopped the scheduler, else 64 * {@code false} if already stopped (a <b>shared</b> thread 65 * pool was shutdown externally). 66 * @throws InterruptedException if interrupted while waiting 67 * for scheduled tasks to finish 68 * @see org.junit.runners.model.RunnerScheduler#finished() 69 */ 70 protected abstract boolean finished() throws InterruptedException; 71 72 /** 73 * Stops scheduling new tasks (e.g. by {@link java.util.concurrent.ExecutorService#shutdown()} 74 * on a private thread pool which cannot be <b>shared</b> with other strategy). 75 * 76 * @return {@code true} if successfully stopped the scheduler, else 77 * {@code false} if already stopped (a <b>shared</b> thread 78 * pool was shutdown externally). 79 * @see java.util.concurrent.ExecutorService#shutdown() 80 */ 81 protected abstract boolean stop(); 82 83 /** 84 * Stops scheduling new tasks and {@code interrupts} running tasks 85 * (e.g. by {@link java.util.concurrent.ExecutorService#shutdownNow()} on a private thread pool 86 * which cannot be <b>shared</b> with other strategy). 87 * <br> 88 * This method calls {@link #stop()} by default. 89 * 90 * @return {@code true} if successfully stopped the scheduler, else 91 * {@code false} if already stopped (a <b>shared</b> thread 92 * pool was shutdown externally). 93 * @see java.util.concurrent.ExecutorService#shutdownNow() 94 */ 95 protected boolean stopNow() { 96 return stop(); 97 } 98 99 /** 100 * Persistently disables this strategy. Atomically ignores {@link Balancer} to acquire a new permit.<br> 101 * The method {@link #canSchedule()} atomically returns {@code false}. 102 * @return {@code true} if {@link #canSchedule()} has return {@code true} on the beginning of this method call. 103 */ 104 protected boolean disable() { 105 return canSchedule.getAndSet(false); 106 } 107 108 protected void setDefaultShutdownHandler(Scheduler.ShutdownHandler handler) {} 109 110 /** 111 * @return {@code true} 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 {@code true} unless stopped, finished or disabled. 118 */ 119 protected boolean canSchedule() { 120 return canSchedule.get(); 121 } 122 123 protected void logQuietly(Throwable t) { 124 logger.error(t); 125 } 126 }