1 /* 2 * This file is part of AceLogger. 3 * 4 * AceLogger is free software: you can redistribute it and/or modify it under the terms of the GNU 5 * Lesser General Public License as published by the Free Software Foundation, either version 3 of 6 * the License, or (at your option) any later version. 7 * 8 * AceLogger is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 9 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 * Lesser General Public License for more details. 11 * 12 * You should have received a copy of the GNU Lesser General Public License along with AceLogger. 13 * If not, see <http://www.gnu.org/licenses/lgpl-3.0.html>. 14 */ 15 package net.sourceforge.acelogger.execution.task; 16 17 /** 18 * A {@link Runnable} implementation and a wrapper that supports monitoring of the execution status 19 * and a utility methods to await the task completion or a given timeout, what occurs first. 20 * 21 * @author Zardi (https://sourceforge.net/users/daniel_zardi) 22 * @version 1.0.0 23 * @since 1.0.0 24 */ 25 public class MonitorableTask implements Runnable { 26 27 /** 28 * The default value (in ms) for the maximum step used in termination waiting methods. 29 */ 30 public static final int DEFAULT_MAXIMUM_STEP = 200; 31 32 /** 33 * Signals if this task has terminated execution or not. 34 */ 35 private boolean done; 36 37 /** 38 * The task that will be monitored for execution. 39 */ 40 private final Runnable task; 41 42 /** 43 * Constructs a new MonitorableTask for the given {@link Runnable}. 44 * 45 * @param task 46 * The {@link Runnable} that will be monitored. 47 * @since 1.0.0 48 */ 49 public MonitorableTask(Runnable task) { 50 this.task = task; 51 done = false; 52 } 53 54 /** {@inheritDoc} */ 55 public void run() { 56 task.run(); 57 done = true; 58 } 59 60 /** 61 * Signals the termination of this task execution. 62 * 63 * @return True if the task has already run; False otherwise. 64 */ 65 public boolean isDone() { 66 return done; 67 } 68 69 /** 70 * Waits for task completion or waiting timeout, what occurs first. This method will use a 71 * default step defined in {@link MonitorableTask#DEFAULT_MAXIMUM_STEP}. 72 * 73 * @param duration 74 * The maximum duration of the waiting process, in milliseconds. 75 * @return True if the task was done; False otherwise (timeout occurred). 76 * @see MonitorableTask#awaitTermination(long, long) 77 * @throws InterruptedException 78 * If the execution thread was interrupted during the waiting process. 79 * @since 1.0.0 80 */ 81 public boolean awaitTermination(long duration) throws InterruptedException { 82 return awaitTermination(duration, DEFAULT_MAXIMUM_STEP); 83 } 84 85 /** 86 * Waits for task completion or waiting timeout, what occurs first. The waiting process will be 87 * "sliced" using the supplied maximum step value. 88 * 89 * @param duration 90 * The maximum duration of the waiting process, in milliseconds. 91 * @param maximumStep 92 * The maximum step during the waiting process, in milliseconds. 93 * @return True if the task was done; False otherwise (timeout occurred). 94 * @throws InterruptedException 95 * If the execution thread was interrupted during the waiting process. 96 * @since 1.0.0 97 */ 98 public boolean awaitTermination(long duration, long maximumStep) throws InterruptedException { 99 long left = duration; 100 long wait = maximumStep; 101 while (left > 0 && !done) { 102 if (left < wait) { 103 wait = left; 104 } 105 Thread.sleep(wait); 106 left -= wait; 107 } 108 return done; 109 } 110 111 }