通常在我们会有需求实现跑一个定时任务,或者每隔一段时间跑一遍数据。
下面是实现方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
static long PERIOD = 24; //执行周期(以小时为单位) /** * 定时器 */ static { ScheduledExecutorService service = Executors.newScheduledThreadPool(1); Runnable syncCallHistory = new Runnable() { public void run() { try { log.info("同步酷讯旅游线路记录任务开始..."); TaskUtil.doStart(); log.info("同步酷讯旅游线路记录任务结束..."); } catch (Exception e) { log.error(e.getMessage()); } } }; service.scheduleAtFixedRate(syncCallHistory, getTimeLong(), PERIOD, TimeUnit.HOURS); } /** * 取得首次执行延时时间 * @return */ public static long getTimeLong() { Date d = new Date() ; SimpleDateFormat sf = new SimpleDateFormat("HH"); String hour = sf.format(d); int timeDifference = 0; if (Constants.DOTASKTIME > Integer.parseInt(hour)) {//判断执行时间 大于当前时间 则当天执行 timeDifference = Constants.DOTASKTIME - Integer.parseInt(hour); } else {// 执行时间 小于等于 当前时间 隔天执行 timeDifference = Constants.DOTASKTIME + 24 - Integer.parseInt(hour); } log.info("定时器将在"+timeDifference+"后小时执行"); System.out.println("定时器将在"+timeDifference+"后小时执行"); return timeDifference; } |
解释下 Executors 这个类
此类是个
此类支持以下
* 创建并返回设置有常用配置的ExecutorService的方法。
* 创建并返回设置有常用配置的ScheduledExecutorService 的方法。
* 创建并返回“包装的”ExecutorService 方法,它使特定于实现的方法不可访问,只让ExecutorService接口的方法可用。
* 创建并返回 ThreadFactory 的方法,它可将新创建的线程设置为已知的状态。
* 创建并返回非闭包形式的 Callable 的方法,这样可将其用于需要 Callable 的执行方法中。
其中,主要方法:
1 |
public static ExecutorService newFixedThreadPool(int nThreads) |
创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。
在任意点,在大多数 nThreads 线程会处于处理任务的活动状态。如果在所有线程处于活动状态时提交附加任务,
则在有可用线程之前,附加任务将在队列中等待。如果在关闭前的执行期间由于失败而导致任何线程终止,
那么一个新线程将代替它执行后续的任务(如果需要)。在某个线程被显式地关闭之前,池中的线程将一直存在。
参数:
nThreads – 池中的线程数
返回:
新创建的线程池
抛出:
IllegalArgumentException – 如果 nThreads <= 0
return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
1 |
public static ExecutorService newFixedThreadPool(int nThreads,ThreadFactory threadFactory) |
创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程,在需要时使用提供的 ThreadFactory 创建新线程。在任意点,在大 多数 nThreads 线程会处于处理任务的活动状态。如果在所有线程处于活动状态时提交附加任务,则在有可用线程之前,附加任务将在队列中等待。如果 在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。在某个线程被显式地关闭之前,池中的线程将一直存 在。
参数:
nThreads – 池中的线程数
threadFactory – 创建新线程时使用的工厂
返回:
新创建的线程池
抛出:
NullPointerException – 如果 threadFactory 为 null
IllegalArgumentException – 如果 nThreads <= 0
1 |
public static ExecutorService newSingleThreadExecutor() |
创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
(注意,如果因为在关闭前的执行期间出现失败而终止了此单个线程,那么如果需要,一个新线程将代替它执行后续的任务)。
可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。
与其他等效的 newFixedThreadPool(1) 不同,可保证不能对ThreadPoolExecutor重新进行配置来使用更多的线程。
返回:
新创建的单线程 Executor
newSingleThreadExecutor返回的ExcutorService在析构函数finalize()会调用shutdown(),即如果我们没有对它调用shutdown(),那么可以确保它在被回收时调用shutdown()来终止线程。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));
}
1 |
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) |
创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程,并在需要时使用提供 的 ThreadFactory 创建新线程。与其他等效的 newFixedThreadPool(1, threadFactory) 不同,可保证 不能对ThreadPoolExecutor重新进行配置来使用更多的线程。
参数:
threadFactory – 创建新线程时使用的工厂
返回:
新创建的单线程 Executor
抛出:
NullPointerException – 如果 threadFactory 为 null
1 |
public static ExecutorService newCachedThreadPool() |
这些线程池通常可提高程序性能。调用 execute 将重用以前构造的线程(如果线程可用)。
如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
因此,长时间保持空闲的线程池不会使用任何资源。
注意,可以使用 ThreadPoolExecutor 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。
返回:
新创建的线程池
public static ExecutorService newCachedThreadPool() {
}
1 |
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) |
创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们,并在需要时使用提供的 ThreadFactory 创建新线程。
参数:
threadFactory – 创建新线程时使用的工厂
返回:
新创建的线程池
抛出:
NullPointerException – 如果 threadFactory 为 null
1 |
public static ScheduledExecutorService newSingleThreadScheduledExecutor() |
创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。
(注意,如果因为在关闭前的执行期间出现失败而终止了此单个线程,那么如果需要,一个新线程会代替它执行后续的任务)。
可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。
与其他等效的 newScheduledThreadPool(1) 不同,可保证不能对ScheduledThreadPoolExecutor重新进行配置来使用更多的线程。
返回:
新创建的安排执行程序
newSingleThreadScheduledExecutor在析构函数finalize()会调用shutdown(),即如果我们没有对它调用shutdown(),那么可以确保它在被回收时调用shutdown()来终止线程。
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory)
创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。
(注意,如果因为在关闭前的执行期间出现失败而终止了此单个线程,那么如果需要,一个新线程会代替它执行后续的任务)。
可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。与其他等效 的 newScheduledThreadPool(1, threadFactory) 不同,可保证不能对 ScheduledThreadPoolExecutor重新进行配置来使用更多的线程。
参数:
threadFactory – 创建新线程时使用的工厂
返回:
新创建的安排执行程序
抛出:
NullPointerException – 如果 threadFactory 为 null
1 |
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) |
创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
参数:
corePoolSize – 池中所保存的线程数,即使线程是空闲的也包括在内。
返回:
新创建的安排线程池
抛出:
NullPointerException – 如果 threadFactory 为 null
1 |
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory) |
创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
参数:
corePoolSize – 池中所保存的线程数,即使线程是空闲的也包括在内
threadFactory – 执行程序创建新线程时使用的工厂
返回:
新创建的安排线程池
抛出:
IllegalArgumentException – 如果 corePoolSize < 0
NullPointerException – 如果 threadFactory 为 null
1 |
public static ExecutorService unconfigurableExecutorService(ExecutorService executor) |
返回一个将所有已定义的 ExecutorService 方法委托给指定执行程序的对象,这样就无法使用强制转换来访问其他的方法。
这提供了一种可安全地“冻结”配置并且不允许调整给定具体实现的方法。
参数:
executor – 底层实现
返回:
一个 ExecutorService 实例
抛出:
NullPointerException – 如果 executor 为 null
1 |
public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) |
返回一个将所有已定义的 ExecutorService 方法委托给指定执行程序的对象,这样就无法使用强制转换来访问其他的方法。。这提供了一种可安全地“冻结”配置并且不允许调整给定具体实现的方法。
参数:
executor – 底层实现
返回:
一个 ScheduledExecutorService 实例
抛出:
NullPointerException – 如果 executor 为 null
1 |
public static ThreadFactory defaultThreadFactory() |
返回用于创建新线程的默认线程工厂。此工厂创建同一 ThreadGroup 中 Executor 使用的所有新线程。
如果有 SecurityManager,则它使用 System.getSecurityManager() 组来调用此 defaultThreadFactory 方法,其他情况则使用线程组。
每个新线程都作为非守护程序而创建,并且具有设置为 Thread.NORM_PRIORITY 中较小者的优先级以及线程组中允许的最大优先级。
新线程具有可通过 pool-N-thread-M 的 Thread.getName() 来访问的名称,其中 N 是此工厂的序列号,M 是此工厂所创建线程的序列号。
返回:
线程工厂
1 |
public static ThreadFactory privilegedThreadFactory() |
返回用于创建新线程的线程工厂,这些新线程与当前线程具有相同的权限。此工厂创建具有与 defaultThreadFactory() 相同设置的线程,
新线程的 AccessControlContext 和 contextClassLoader 的其他设置与调用 此 privilegedThreadFactory 方法的线程相同。可以 在 AccessController.doPrivileged(java.security.PrivilegedAction) 操作中创建一个 新 privilegedThreadFactory,设置当前线程的访问控制上下文,以便创建具有该操作中保持的所选权限的线程。
或 InheritableThreadLocal 值。如有必要,使用 ThreadPoolExecutor.beforeExecute(java.lang.Thread, java.lang.Runnable)
在 ThreadPoolExecutor 子类中运行任何任务前,可以设置或重置线程局部变量的特定值。
另外,如果必须初始化 worker 线程,以具有与某些其他指定线程相同的 InheritableThreadLocal 设置,
则可以在线程等待和服务创建请求的环境中创建自定义的 ThreadFactory,而不是继承其值。
返回:
线程工厂
抛出:
AccessControlException – 如果当前访问控制上下文没有获取和设置上下文类加载器的权限。
1 |
public static <T> Callable<T> callable(Runnable task,T result) |
返回 Callable 对象,调用它时可运行给定的任务并返回给定的结果。这在把需要 Callable 的方法应用到其他无结果的操作时很有用。
参数:
task – 要运行的任务
result – 返回的结果
返回:
一个 callable 对象
抛出:
NullPointerException – 如果 task 为 null
1 |
public static Callable<Object> callable(Runnable task) |
返回 Callable 对象,调用它时可运行给定的任务并返回 null。
参数:
task – 要运行的任务
返回:
一个 callable 对象
抛出:
NullPointerException – 如果 task 为 null
1 |
public static Callable<Object> callable(PrivilegedAction<?> action) |
返回 Callable 对象,调用它时可运行给定特权的操作并返回其结果。
参数:
action – 要运行的特权操作
返回:
一个 callable 对象
抛出:
NullPointerException – 如果 action 为 null
转载请注明:刘召考的博客 » Java事件定时任务的实现