154 * @throws InterruptedException if the current thread is |
155 * @throws InterruptedException if the current thread is |
155 * {@linkplain Thread#interrupt() interrupted} by another |
156 * {@linkplain Thread#interrupt() interrupted} by another |
156 * thread while it is waiting, then the wait is ended and |
157 * thread while it is waiting, then the wait is ended and |
157 * an {@link InterruptedException} is thrown. |
158 * an {@link InterruptedException} is thrown. |
158 */ |
159 */ |
159 abstract public int waitFor() throws InterruptedException; |
160 public abstract int waitFor() throws InterruptedException; |
|
161 |
|
162 /** |
|
163 * Causes the current thread to wait, if necessary, until the |
|
164 * subprocess represented by this {@code Process} object has |
|
165 * terminated, or the specified waiting time elapses. |
|
166 * |
|
167 * <p>If the subprocess has already terminated then this method returns |
|
168 * immediately with the value {@code true}. If the process has not |
|
169 * terminated and the timeout value is less than, or equal to, zero, then |
|
170 * this method returns immediately with the value {@code false}. |
|
171 * |
|
172 * <p>The default implementation of this methods polls the {@code exitValue} |
|
173 * to check if the process has terminated. Concrete implementations of this |
|
174 * class are strongly encouraged to override this method with a more |
|
175 * efficient implementation. |
|
176 * |
|
177 * @param timeout the maximum time to wait |
|
178 * @param unit the time unit of the {@code timeout} argument |
|
179 * @return {@code true} if the subprocess has exited and {@code false} if |
|
180 * the waiting time elapsed before the subprocess has exited. |
|
181 * @throws InterruptedException if the current thread is interrupted |
|
182 * while waiting. |
|
183 * @throws NullPointerException if unit is null |
|
184 * @since 1.8 |
|
185 */ |
|
186 public boolean waitFor(long timeout, TimeUnit unit) |
|
187 throws InterruptedException |
|
188 { |
|
189 long startTime = System.nanoTime(); |
|
190 long rem = unit.toNanos(timeout); |
|
191 |
|
192 do { |
|
193 try { |
|
194 exitValue(); |
|
195 return true; |
|
196 } catch(IllegalThreadStateException ex) { |
|
197 if (rem > 0) |
|
198 Thread.sleep( |
|
199 Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100)); |
|
200 } |
|
201 rem = unit.toNanos(timeout) - (System.nanoTime() - startTime); |
|
202 } while (rem > 0); |
|
203 return false; |
|
204 } |
160 |
205 |
161 /** |
206 /** |
162 * Returns the exit value for the subprocess. |
207 * Returns the exit value for the subprocess. |
163 * |
208 * |
164 * @return the exit value of the subprocess represented by this |
209 * @return the exit value of the subprocess represented by this |
165 * {@code Process} object. By convention, the value |
210 * {@code Process} object. By convention, the value |
166 * {@code 0} indicates normal termination. |
211 * {@code 0} indicates normal termination. |
167 * @throws IllegalThreadStateException if the subprocess represented |
212 * @throws IllegalThreadStateException if the subprocess represented |
168 * by this {@code Process} object has not yet terminated |
213 * by this {@code Process} object has not yet terminated |
169 */ |
214 */ |
170 abstract public int exitValue(); |
215 public abstract int exitValue(); |
|
216 |
|
217 /** |
|
218 * Kills the subprocess. Whether the subprocess represented by this |
|
219 * {@code Process} object is forcibly terminated or not is |
|
220 * implementation dependent. |
|
221 */ |
|
222 public abstract void destroy(); |
171 |
223 |
172 /** |
224 /** |
173 * Kills the subprocess. The subprocess represented by this |
225 * Kills the subprocess. The subprocess represented by this |
174 * {@code Process} object is forcibly terminated. |
226 * {@code Process} object is forcibly terminated. |
175 */ |
227 * |
176 abstract public void destroy(); |
228 * <p>The default implementation of this method invokes {@link #destroy} |
|
229 * and so may not forcibly terminate the process. Concrete implementations |
|
230 * of this class are strongly encouraged to override this method with a |
|
231 * compliant implementation. Invoking this method on {@code Process} |
|
232 * objects returned by {@link ProcessBuilder#start} and |
|
233 * {@link Runtime#exec} will forcibly terminate the process. |
|
234 * |
|
235 * <p>Note: The subprocess may not terminate immediately. |
|
236 * i.e. {@code isAlive()} may return true for a brief period |
|
237 * after {@code destroyForcibly()} is called. This method |
|
238 * may be chained to {@code waitFor()} if needed. |
|
239 * |
|
240 * @return the {@code Process} object representing the |
|
241 * subprocess to be forcibly destroyed. |
|
242 * @since 1.8 |
|
243 */ |
|
244 public Process destroyForcibly() { |
|
245 destroy(); |
|
246 return this; |
|
247 } |
|
248 |
|
249 /** |
|
250 * Tests whether the subprocess represented by this {@code Process} is |
|
251 * alive. |
|
252 * |
|
253 * @return {@code true} if the subprocess represented by this |
|
254 * {@code Process} object has not yet terminated. |
|
255 * @since 1.8 |
|
256 */ |
|
257 public boolean isAlive() { |
|
258 try { |
|
259 exitValue(); |
|
260 return false; |
|
261 } catch(IllegalThreadStateException e) { |
|
262 return true; |
|
263 } |
|
264 } |
177 } |
265 } |