Java tutorial
/* * Copyright (C) 2011 Google Inc. * * 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.ros.concurrent; import com.google.common.base.Preconditions; import java.util.concurrent.ExecutorService; /** * An interruptable loop that can be run by an {@link ExecutorService}. * * @author khughes@google.com (Keith M. Hughes) */ public abstract class CancellableLoop implements Runnable { private final Object mutex; /** * {@code true} if the code has been run once, {@code false} otherwise. */ private boolean ranOnce = false; /** * The {@link Thread} the code will be running in. */ private Thread thread; public CancellableLoop() { mutex = new Object(); } @Override public void run() { synchronized (mutex) { Preconditions.checkState(!ranOnce, "CancellableLoops cannot be restarted."); ranOnce = true; thread = Thread.currentThread(); } try { setup(); while (!thread.isInterrupted()) { loop(); } } catch (InterruptedException e) { handleInterruptedException(e); } finally { thread = null; cleanup(); } } /** * The setup block for the loop. This will be called exactly once before the * first call to {@link #loop()}. */ protected void setup() { } /** * The cleanup block for the loop. This will be called exactly once when the * loop has shut down. */ protected void cleanup() { } /** * The body of the loop. This will run continuously until the * {@link CancellableLoop} has been interrupted externally or by calling * {@link #cancel()}. */ protected abstract void loop() throws InterruptedException; /** * An {@link InterruptedException} was thrown. */ protected void handleInterruptedException(InterruptedException e) { } /** * Interrupts the loop. */ public void cancel() { if (thread != null) { thread.interrupt(); } } /** * @return {@code true} if the loop is running */ public boolean isRunning() { return thread != null && !thread.isInterrupted(); } }