Coverage Report - org.apache.commons.io.ThreadMonitor
 
Classes in this File Line Coverage Branch Coverage Complexity
ThreadMonitor
100%
26/26
83%
5/6
1.667
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.commons.io;
 18  
 
 19  
 /**
 20  
  * Monitors a thread, interrupting it if it reaches the specified timeout.
 21  
  * <p>
 22  
  * This works by sleeping until the specified timeout amount and then
 23  
  * interrupting the thread being monitored. If the thread being monitored
 24  
  * completes its work before being interrupted, it should <code>interrupt()</code>
 25  
  * the <i>monitor</i> thread.
 26  
  * </p>
 27  
  * 
 28  
  * <pre>
 29  
  *       long timeoutInMillis = 1000;
 30  
  *       try {
 31  
  *           Thread monitor = ThreadMonitor.start(timeoutInMillis);
 32  
  *           // do some work here
 33  
  *           ThreadMonitor.stop(monitor);
 34  
  *       } catch (InterruptedException e) {
 35  
  *           // timed amount was reached
 36  
  *       }
 37  
  * </pre>
 38  
  *
 39  
  * @version  $Id: ThreadMonitor.java 1718945 2015-12-09 19:51:14Z krosenvold $
 40  
  */
 41  
 class ThreadMonitor implements Runnable {
 42  
 
 43  
     private final Thread thread;
 44  
     private final long timeout;
 45  
 
 46  
     /**
 47  
      * Start monitoring the current thread.
 48  
      *
 49  
      * @param timeout The timeout amount in milliseconds
 50  
      * or no timeout if the value is zero or less
 51  
      * @return The monitor thread or {@code null}
 52  
      * if the timeout amount is not greater than zero
 53  
      */
 54  
     public static Thread start(final long timeout) {
 55  42
         return start(Thread.currentThread(), timeout);
 56  
     }
 57  
 
 58  
     /**
 59  
      * Start monitoring the specified thread.
 60  
      *
 61  
      * @param thread The thread The thread to monitor
 62  
      * @param timeout The timeout amount in milliseconds
 63  
      * or no timeout if the value is zero or less
 64  
      * @return The monitor thread or {@code null}
 65  
      * if the timeout amount is not greater than zero
 66  
      */
 67  
     public static Thread start(final Thread thread, final long timeout) {
 68  42
         Thread monitor = null;
 69  42
         if (timeout > 0) {
 70  2
             final ThreadMonitor timout = new ThreadMonitor(thread, timeout);
 71  2
             monitor = new Thread(timout, ThreadMonitor.class.getSimpleName());
 72  2
             monitor.setDaemon(true);
 73  2
             monitor.start();
 74  
         }
 75  42
         return monitor;
 76  
     }
 77  
 
 78  
     /**
 79  
      * Stop monitoring the specified thread.
 80  
      *
 81  
      * @param thread The monitor thread, may be {@code null}
 82  
      */
 83  
     public static void stop(final Thread thread) {
 84  41
         if (thread != null) {
 85  1
             thread.interrupt();
 86  
         }
 87  41
     }
 88  
 
 89  
     /**
 90  
      * Construct and new monitor.
 91  
      *
 92  
      * @param thread The thread to monitor
 93  
      * @param timeout The timeout amount in milliseconds
 94  
      */
 95  2
     private ThreadMonitor(final Thread thread, final long timeout) {
 96  2
         this.thread = thread;
 97  2
         this.timeout = timeout;
 98  2
     }
 99  
 
 100  
     /**
 101  
      * Sleep until the specified timeout amount and then
 102  
      * interrupt the thread being monitored.
 103  
      *
 104  
      * @see Runnable#run()
 105  
      */
 106  
     public void run() {
 107  
         try {
 108  2
             sleep(timeout);
 109  1
             thread.interrupt();
 110  1
         } catch (final InterruptedException e) {
 111  
             // timeout not reached
 112  1
         }
 113  2
     }
 114  
 
 115  
     /**
 116  
      * Sleep for a guaranteed minimum number of milliseconds unless interrupted.
 117  
      *
 118  
      * This method exists because Thread.sleep(100) can sleep for 0, 70, 100 or 200ms or anything else
 119  
      * it deems appropriate. Read the docs on Thread.sleep for further interesting details.
 120  
      * @
 121  
      * @param ms the number of milliseconds to sleep for
 122  
      * @throws InterruptedException if interrupted
 123  
      */
 124  
     private static void sleep(long ms) throws InterruptedException {
 125  2
         long finishAt = System.currentTimeMillis() + ms;
 126  2
         long remaining = ms;
 127  
         do {
 128  2
             Thread.sleep(remaining);
 129  1
             remaining = finishAt - System.currentTimeMillis();
 130  1
         } while (remaining > 0);
 131  1
     }
 132  
 
 133  
 
 134  
 }