001/*
002 * Copyright 2002-2017 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.concurrent;
018
019import java.util.concurrent.TimeUnit;
020
021import org.springframework.lang.Nullable;
022import org.springframework.util.Assert;
023
024/**
025 * JavaBean that describes a scheduled executor task, consisting of the
026 * {@link Runnable} and a delay plus period. The period needs to be specified;
027 * there is no point in a default for it.
028 *
029 * <p>The {@link java.util.concurrent.ScheduledExecutorService} does not offer
030 * more sophisticated scheduling options such as cron expressions.
031 * Consider using {@link ThreadPoolTaskScheduler} for such needs.
032 *
033 * <p>Note that the {@link java.util.concurrent.ScheduledExecutorService} mechanism
034 * uses a {@link Runnable} instance that is shared between repeated executions,
035 * in contrast to Quartz which creates a new Job instance for each execution.
036 *
037 * @author Juergen Hoeller
038 * @since 2.0
039 * @see java.util.concurrent.ScheduledExecutorService#scheduleWithFixedDelay(java.lang.Runnable, long, long, java.util.concurrent.TimeUnit)
040 * @see java.util.concurrent.ScheduledExecutorService#scheduleAtFixedRate(java.lang.Runnable, long, long, java.util.concurrent.TimeUnit)
041 */
042public class ScheduledExecutorTask {
043
044        @Nullable
045        private Runnable runnable;
046
047        private long delay = 0;
048
049        private long period = -1;
050
051        private TimeUnit timeUnit = TimeUnit.MILLISECONDS;
052
053        private boolean fixedRate = false;
054
055
056        /**
057         * Create a new ScheduledExecutorTask,
058         * to be populated via bean properties.
059         * @see #setDelay
060         * @see #setPeriod
061         * @see #setFixedRate
062         */
063        public ScheduledExecutorTask() {
064        }
065
066        /**
067         * Create a new ScheduledExecutorTask, with default
068         * one-time execution without delay.
069         * @param executorTask the Runnable to schedule
070         */
071        public ScheduledExecutorTask(Runnable executorTask) {
072                this.runnable = executorTask;
073        }
074
075        /**
076         * Create a new ScheduledExecutorTask, with default
077         * one-time execution with the given delay.
078         * @param executorTask the Runnable to schedule
079         * @param delay the delay before starting the task for the first time (ms)
080         */
081        public ScheduledExecutorTask(Runnable executorTask, long delay) {
082                this.runnable = executorTask;
083                this.delay = delay;
084        }
085
086        /**
087         * Create a new ScheduledExecutorTask.
088         * @param executorTask the Runnable to schedule
089         * @param delay the delay before starting the task for the first time (ms)
090         * @param period the period between repeated task executions (ms)
091         * @param fixedRate whether to schedule as fixed-rate execution
092         */
093        public ScheduledExecutorTask(Runnable executorTask, long delay, long period, boolean fixedRate) {
094                this.runnable = executorTask;
095                this.delay = delay;
096                this.period = period;
097                this.fixedRate = fixedRate;
098        }
099
100
101        /**
102         * Set the Runnable to schedule as executor task.
103         */
104        public void setRunnable(Runnable executorTask) {
105                this.runnable = executorTask;
106        }
107
108        /**
109         * Return the Runnable to schedule as executor task.
110         */
111        public Runnable getRunnable() {
112                Assert.state(this.runnable != null, "No Runnable set");
113                return this.runnable;
114        }
115
116        /**
117         * Set the delay before starting the task for the first time,
118         * in milliseconds. Default is 0, immediately starting the
119         * task after successful scheduling.
120         */
121        public void setDelay(long delay) {
122                this.delay = delay;
123        }
124
125        /**
126         * Return the delay before starting the job for the first time.
127         */
128        public long getDelay() {
129                return this.delay;
130        }
131
132        /**
133         * Set the period between repeated task executions, in milliseconds.
134         * <p>Default is -1, leading to one-time execution. In case of a positive value,
135         * the task will be executed repeatedly, with the given interval in-between executions.
136         * <p>Note that the semantics of the period value vary between fixed-rate and
137         * fixed-delay execution.
138         * <p><b>Note:</b> A period of 0 (for example as fixed delay) is <i>not</i> supported,
139         * simply because {@code java.util.concurrent.ScheduledExecutorService} itself
140         * does not support it. Hence a value of 0 will be treated as one-time execution;
141         * however, that value should never be specified explicitly in the first place!
142         * @see #setFixedRate
143         * @see #isOneTimeTask()
144         * @see java.util.concurrent.ScheduledExecutorService#scheduleWithFixedDelay(Runnable, long, long, java.util.concurrent.TimeUnit)
145         */
146        public void setPeriod(long period) {
147                this.period = period;
148        }
149
150        /**
151         * Return the period between repeated task executions.
152         */
153        public long getPeriod() {
154                return this.period;
155        }
156
157        /**
158         * Is this task only ever going to execute once?
159         * @return {@code true} if this task is only ever going to execute once
160         * @see #getPeriod()
161         */
162        public boolean isOneTimeTask() {
163                return (this.period <= 0);
164        }
165
166        /**
167         * Specify the time unit for the delay and period values.
168         * Default is milliseconds ({@code TimeUnit.MILLISECONDS}).
169         * @see java.util.concurrent.TimeUnit#MILLISECONDS
170         * @see java.util.concurrent.TimeUnit#SECONDS
171         */
172        public void setTimeUnit(@Nullable TimeUnit timeUnit) {
173                this.timeUnit = (timeUnit != null ? timeUnit : TimeUnit.MILLISECONDS);
174        }
175
176        /**
177         * Return the time unit for the delay and period values.
178         */
179        public TimeUnit getTimeUnit() {
180                return this.timeUnit;
181        }
182
183        /**
184         * Set whether to schedule as fixed-rate execution, rather than
185         * fixed-delay execution. Default is "false", that is, fixed delay.
186         * <p>See ScheduledExecutorService javadoc for details on those execution modes.
187         * @see java.util.concurrent.ScheduledExecutorService#scheduleWithFixedDelay(java.lang.Runnable, long, long, java.util.concurrent.TimeUnit)
188         * @see java.util.concurrent.ScheduledExecutorService#scheduleAtFixedRate(java.lang.Runnable, long, long, java.util.concurrent.TimeUnit)
189         */
190        public void setFixedRate(boolean fixedRate) {
191                this.fixedRate = fixedRate;
192        }
193
194        /**
195         * Return whether to schedule as fixed-rate execution.
196         */
197        public boolean isFixedRate() {
198                return this.fixedRate;
199        }
200
201}