📄 inaccuratetimeoutwatchdog.java
字号:
/*********************************************************************** * Copyright (c) 2000-2004 The Apache Software Foundation. * * All rights reserved. * * ------------------------------------------------------------------- * * Licensed under the Apache License, Version 2.0 (the "License"); you * * may not use this file except in compliance with the License. You * * may obtain a copy of the License at: * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * * implied. See the License for the specific language governing * * permissions and limitations under the License. * ***********************************************************************/package org.apache.james.util.watchdog;import org.apache.avalon.excalibur.thread.ThreadPool;import org.apache.avalon.framework.activity.Disposable;import org.apache.avalon.framework.logger.AbstractLogEnabled;/** * This class represents an watchdog process that serves to * monitor a situation and triggers an action after a certain time has * passed. This implementation is deliberately inaccurate, trading * accuracy for minimal impact on reset. This should be used when * the time of the Watchdog trigger is not critical, and a high number * of resets are expected. * */public class InaccurateTimeoutWatchdog extends AbstractLogEnabled implements Watchdog, Runnable, Disposable { /** * Whether the watchdog is currently checking the trigger condition */ private volatile boolean isChecking = false; /** * Whether the watchdog has been reset since the thread slept. */ private volatile boolean isReset = false; /** * The number of milliseconds until the watchdog times out. */ private final long timeout; /** * The last time the internal timer was reset, as measured in milliseconds since * January 1, 1970 00:00:00.000 GMT. */ private volatile long lastReset; /** * The WatchdogTarget whose execute() method will be called upon triggering * of the condition. */ private WatchdogTarget triggerTarget; /** * The thread that runs the watchdog. */ private Thread watchdogThread; /** * The thread pool used to generate InaccurateTimeoutWatchdogs */ private ThreadPool myThreadPool; /** * The sole constructor for the InaccurateTimeoutWatchdog * * @param timeout the time (in msec) that it will take the Watchdog to timeout * @param target the WatchdogTarget to be executed when this Watchdog expires * @param threadPool the thread pool used to generate threads for this implementation. */ public InaccurateTimeoutWatchdog(long timeout, WatchdogTarget target, ThreadPool threadPool) { if (target == null) { throw new IllegalArgumentException("The WatchdogTarget for this TimeoutWatchdog cannot be null."); } if (threadPool == null) { throw new IllegalArgumentException("The thread pool for this TimeoutWatchdog cannot be null."); } this.timeout = timeout; triggerTarget = target; myThreadPool = threadPool; } /** * Start this Watchdog, causing it to begin checking. */ public void start() { getLogger().debug("Calling start()"); lastReset = System.currentTimeMillis(); isChecking = true; synchronized(this) { if ( watchdogThread == null) { myThreadPool.execute(this); } } } /** * Reset this Watchdog. Tells the Watchdog thread to reset * the timer when it next awakens. */ public void reset() { if (watchdogThread != null) { getLogger().debug("Calling reset() " + watchdogThread.getName()); } else { getLogger().debug("Calling reset() for inactive watchdog"); } isReset = true; } /** * Stop this Watchdog, causing the Watchdog to stop checking the trigger * condition. The monitor can be restarted with a call to startWatchdog. */ public void stop() { if (watchdogThread != null) { getLogger().debug("Calling stop() " + watchdogThread.getName()); } else { getLogger().debug("Calling stop() for inactive watchdog"); } isChecking = false; } /** * Execute the body of the Watchdog, triggering as appropriate. */ public void run() { try { watchdogThread = Thread.currentThread(); while ((!(Thread.currentThread().interrupted())) && (watchdogThread != null)) { try { if (!isChecking) { if (getLogger().isDebugEnabled()) { getLogger().debug("Watchdog " + Thread.currentThread().getName() + " is not active - going to exit."); } synchronized (this) { if (!isChecking) { watchdogThread = null; } continue; } } else { long currentTime = System.currentTimeMillis(); if (isReset) { isReset = false; lastReset = currentTime; } long timeToSleep = lastReset + timeout - currentTime; if (watchdogThread != null) { getLogger().debug("Watchdog " + watchdogThread.getName() + " has time to sleep " + timeToSleep); } else { getLogger().debug("Watchdog has time to sleep " + timeToSleep); } if (timeToSleep <= 0) { try { synchronized (this) { if ((isChecking) && (triggerTarget != null)) { triggerTarget.execute(); } watchdogThread = null; } } catch (Throwable t) { getLogger().error("Encountered error while executing Watchdog target.", t); } isChecking = false; continue; } else { synchronized(this) { wait(timeToSleep); } } } } catch (InterruptedException ie) { } } synchronized( this ) { watchdogThread = null; } } finally { // Ensure that the thread is in a non-interrupted state when it gets returned // to the pool. Thread.currentThread().interrupted(); } getLogger().debug("Watchdog " + Thread.currentThread().getName() + " is exiting run()."); } /** * @see org.apache.avalon.framework.activity.Disposable#dispose() */ public void dispose() { synchronized(this) { isChecking = false; if (watchdogThread != null) { getLogger().debug("Calling disposeWatchdog() " + watchdogThread.getName()); } else { getLogger().debug("Calling disposeWatchdog() for inactive watchdog"); } if (watchdogThread != null) { watchdogThread = null; notifyAll(); } if (triggerTarget instanceof Disposable) { ((Disposable)triggerTarget).dispose(); } triggerTarget = null; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -