Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. The ASF licenses this file to You * 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. For additional information regarding * copyright in this work, please see the NOTICE file in the top level * directory of this distribution. */ package org.apache.roller.weblogger.business.runnable; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.roller.weblogger.WebloggerException; import org.apache.roller.weblogger.business.InitializationException; import org.apache.roller.weblogger.config.WebloggerConfig; import org.apache.roller.weblogger.pojos.TaskLock; /** * Manage Roller's thread use. */ @com.google.inject.Singleton public abstract class ThreadManagerImpl implements ThreadManager { private static final Log log = LogFactory.getLog(ThreadManagerImpl.class); // our own scheduler thread private Thread schedulerThread = null; // a simple thread executor private final ExecutorService serviceScheduler; public ThreadManagerImpl() { log.info("Instantiating Thread Manager"); serviceScheduler = Executors.newCachedThreadPool(); } public void initialize() throws InitializationException { // initialize tasks, making sure that each task has a tasklock record in the db List<RollerTask> webloggerTasks = new ArrayList<RollerTask>(); String tasksStr = WebloggerConfig.getProperty("tasks.enabled"); String[] tasks = StringUtils.stripAll(StringUtils.split(tasksStr, ",")); for (String taskName : tasks) { String taskClassName = WebloggerConfig.getProperty("tasks." + taskName + ".class"); if (taskClassName != null) { log.info("Initializing task: " + taskName); try { Class taskClass = Class.forName(taskClassName); RollerTask task = (RollerTask) taskClass.newInstance(); task.init(taskName); // make sure there is a tasklock record in the db TaskLock taskLock = getTaskLockByName(task.getName()); if (taskLock == null) { log.debug("Task record does not exist, inserting empty record to start with"); // insert an empty record taskLock = new TaskLock(); taskLock.setName(task.getName()); taskLock.setLastRun(new Date(0)); taskLock.setTimeAquired(new Date(0)); taskLock.setTimeLeased(0); // save it this.saveTaskLock(taskLock); } // add it to the list of configured tasks webloggerTasks.add(task); } catch (ClassCastException ex) { log.warn("Task does not extend RollerTask class", ex); } catch (WebloggerException ex) { log.error("Error scheduling task", ex); } catch (Exception ex) { log.error("Error instantiating task", ex); } } } // create scheduler TaskScheduler scheduler = new TaskScheduler(webloggerTasks); // start scheduler thread, but only if it's not already running if (schedulerThread == null && scheduler != null) { log.debug("Starting scheduler thread"); schedulerThread = new Thread(scheduler, "Roller Weblogger Task Scheduler"); // set thread priority between MAX and NORM so we get slightly preferential treatment schedulerThread.setPriority((Thread.MAX_PRIORITY + Thread.NORM_PRIORITY) / 2); schedulerThread.start(); } } public void executeInBackground(Runnable runnable) throws InterruptedException { Future task = serviceScheduler.submit(runnable); } public void executeInForeground(Runnable runnable) throws InterruptedException { Future task = serviceScheduler.submit(runnable); // since this task is really meant to be executed within this calling // thread, here we can add a little code here to loop until it realizes // the task is done while (!task.isDone()) { Thread.sleep(500); } } public void shutdown() { log.debug("starting shutdown sequence"); // trigger an immediate shutdown of any backgrounded tasks serviceScheduler.shutdownNow(); // only stop if we are already running if (schedulerThread != null) { log.debug("Stopping scheduler"); schedulerThread.interrupt(); } } public void release() { // no-op } /** * Default implementation of lease registration, always returns true. * * Subclasses should override this method if they plan to run in an * environment that supports clustered deployments. */ public boolean registerLease(RollerTask task) { return true; } /** * Default implementation of lease unregistration, always returns true. * * Subclasses should override this method if they plan to run in an * environment that supports clustered deployments. */ public boolean unregisterLease(RollerTask task) { return true; } }