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 */ 021package net.sf.hajdbc.util.concurrent; 022 023import java.util.Date; 024import java.util.concurrent.CancellationException; 025import java.util.concurrent.RejectedExecutionException; 026import java.util.concurrent.RejectedExecutionHandler; 027import java.util.concurrent.ScheduledThreadPoolExecutor; 028import java.util.concurrent.TimeUnit; 029 030import org.quartz.CronExpression; 031import org.slf4j.Logger; 032import 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 */ 040public class CronThreadPoolExecutor extends ScheduledThreadPoolExecutor implements CronExecutorService 041{ 042 protected static Logger logger = LoggerFactory.getLogger(CronThreadPoolExecutor.class); 043 044 /** 045 * Constructs a new CronThreadPoolExecutor. 046 * @param corePoolSize 047 * @param handler 048 */ 049 public CronThreadPoolExecutor(int corePoolSize, RejectedExecutionHandler handler) 050 { 051 super(corePoolSize, DaemonThreadFactory.getInstance(), handler); 052 } 053 054 /** 055 * Constructs a new CronThreadPoolExecutor. 056 * @param corePoolSize 057 */ 058 public CronThreadPoolExecutor(int corePoolSize) 059 { 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, final CronExpression expression) 068 { 069 if (task == null) throw new NullPointerException(); 070 071 this.setCorePoolSize(this.getCorePoolSize() + 1); 072 073 Runnable scheduleTask = new Runnable() 074 { 075 /** 076 * @see java.lang.Runnable#run() 077 */ 078 public void run() 079 { 080 Date now = new Date(); 081 Date time = expression.getNextValidTimeAfter(now); 082 083 try 084 { 085 while (time != null) 086 { 087 CronThreadPoolExecutor.this.schedule(task, time.getTime() - now.getTime(), TimeUnit.MILLISECONDS); 088 089 while (now.before(time)) 090 { 091 Thread.sleep(time.getTime() - now.getTime()); 092 093 now = new Date(); 094 } 095 096 time = expression.getNextValidTimeAfter(now); 097 } 098 } 099 catch (RejectedExecutionException e) 100 { 101 // Occurs if executor was already shutdown when schedule() is called 102 } 103 catch (CancellationException e) 104 { 105 // Occurs when scheduled, but not yet executed tasks are canceled during shutdown 106 } 107 catch (InterruptedException e) 108 { 109 // Occurs when executing tasks are interrupted during shutdownNow() 110 } 111 } 112 }; 113 114 this.execute(scheduleTask); 115 } 116}