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 }