001: /*
002: * HA-JDBC: High-Availability JDBC
003: * Copyright (c) 2004-2007 Paul Ferraro
004: *
005: * This library is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU Lesser General Public License as published by the
007: * Free Software Foundation; either version 2.1 of the License, or (at your
008: * option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
013: * for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public License
016: * along with this library; if not, write to the Free Software Foundation,
017: * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *
019: * Contact: ferraro@users.sourceforge.net
020: */
021: package net.sf.hajdbc.util.concurrent;
022:
023: import java.util.Date;
024: import java.util.concurrent.CancellationException;
025: import java.util.concurrent.RejectedExecutionException;
026: import java.util.concurrent.RejectedExecutionHandler;
027: import java.util.concurrent.ScheduledThreadPoolExecutor;
028: import java.util.concurrent.TimeUnit;
029:
030: import org.quartz.CronExpression;
031: import org.slf4j.Logger;
032: import org.slf4j.LoggerFactory;
033:
034: /**
035: * Scheduled thread-pool executor implementation that leverages a Quartz CronExpression to calculate future execution times for scheduled tasks.
036: *
037: * @author Paul Ferraro
038: * @since 1.1
039: */
040: public class CronThreadPoolExecutor extends ScheduledThreadPoolExecutor
041: implements CronExecutorService {
042: protected static Logger logger = LoggerFactory
043: .getLogger(CronThreadPoolExecutor.class);
044:
045: /**
046: * Constructs a new CronThreadPoolExecutor.
047: * @param corePoolSize
048: * @param handler
049: */
050: public CronThreadPoolExecutor(int corePoolSize,
051: RejectedExecutionHandler handler) {
052: super (corePoolSize, DaemonThreadFactory.getInstance(), handler);
053: }
054:
055: /**
056: * Constructs a new CronThreadPoolExecutor.
057: * @param corePoolSize
058: */
059: public CronThreadPoolExecutor(int corePoolSize) {
060: super (corePoolSize, DaemonThreadFactory.getInstance());
061: }
062:
063: /**
064: * @see net.sf.hajdbc.util.concurrent.CronExecutorService#schedule(java.lang.Runnable, org.quartz.CronExpression)
065: */
066: @Override
067: public void schedule(final Runnable task,
068: final CronExpression expression) {
069: if (task == null)
070: throw new NullPointerException();
071:
072: this .setCorePoolSize(this .getCorePoolSize() + 1);
073:
074: Runnable scheduleTask = new Runnable() {
075: /**
076: * @see java.lang.Runnable#run()
077: */
078: public void run() {
079: Date now = new Date();
080: Date time = expression.getNextValidTimeAfter(now);
081:
082: try {
083: while (time != null) {
084: CronThreadPoolExecutor.this .schedule(task, time
085: .getTime()
086: - now.getTime(), TimeUnit.MILLISECONDS);
087:
088: while (now.before(time)) {
089: Thread
090: .sleep(time.getTime()
091: - now.getTime());
092:
093: now = new Date();
094: }
095:
096: time = expression.getNextValidTimeAfter(now);
097: }
098: } catch (RejectedExecutionException e) {
099: // Occurs if executor was already shutdown when schedule() is called
100: } catch (CancellationException e) {
101: // Occurs when scheduled, but not yet executed tasks are canceled during shutdown
102: } catch (InterruptedException e) {
103: // Occurs when executing tasks are interrupted during shutdownNow()
104: }
105: }
106: };
107:
108: this.execute(scheduleTask);
109: }
110: }
|