001/* 002 * Copyright 2002-2014 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.scheduling.quartz; 018 019import java.util.concurrent.Executor; 020import java.util.concurrent.RejectedExecutionException; 021 022import org.apache.commons.logging.Log; 023import org.apache.commons.logging.LogFactory; 024import org.quartz.SchedulerConfigException; 025import org.quartz.spi.ThreadPool; 026 027/** 028 * Quartz ThreadPool adapter that delegates to a Spring-managed 029 * TaskExecutor instance, specified on SchedulerFactoryBean. 030 * 031 * @author Juergen Hoeller 032 * @since 2.0 033 * @see SchedulerFactoryBean#setTaskExecutor 034 */ 035public class LocalTaskExecutorThreadPool implements ThreadPool { 036 037 /** Logger available to subclasses */ 038 protected final Log logger = LogFactory.getLog(getClass()); 039 040 private Executor taskExecutor; 041 042 043 @Override 044 public void setInstanceId(String schedInstId) { 045 } 046 047 @Override 048 public void setInstanceName(String schedName) { 049 } 050 051 052 @Override 053 public void initialize() throws SchedulerConfigException { 054 // Absolutely needs thread-bound TaskExecutor to initialize. 055 this.taskExecutor = SchedulerFactoryBean.getConfigTimeTaskExecutor(); 056 if (this.taskExecutor == null) { 057 throw new SchedulerConfigException( 058 "No local TaskExecutor found for configuration - " + 059 "'taskExecutor' property must be set on SchedulerFactoryBean"); 060 } 061 } 062 063 @Override 064 public void shutdown(boolean waitForJobsToComplete) { 065 } 066 067 @Override 068 public int getPoolSize() { 069 return -1; 070 } 071 072 073 @Override 074 public boolean runInThread(Runnable runnable) { 075 if (runnable == null) { 076 return false; 077 } 078 try { 079 this.taskExecutor.execute(runnable); 080 return true; 081 } 082 catch (RejectedExecutionException ex) { 083 logger.error("Task has been rejected by TaskExecutor", ex); 084 return false; 085 } 086 } 087 088 @Override 089 public int blockForAvailableThreads() { 090 // The present implementation always returns 1, making Quartz 091 // always schedule any tasks that it feels like scheduling. 092 // This could be made smarter for specific TaskExecutors, 093 // for example calling {@code getMaximumPoolSize() - getActiveCount()} 094 // on a {@code java.util.concurrent.ThreadPoolExecutor}. 095 return 1; 096 } 097 098}