原生的定时任务工具类 https://my.oschina.net/u/2948232/blog/808190 有修改
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
package com.pandy.test;/** * Created by pandy on 16-12-20. */ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * 项目名称: workspace * 功能说明: * 创建者: Pandy, * 邮箱: panyongzheng@163.com, 1453261799@qq.com * 版权: * 官网: * 创建日期: 16-12-20. * 创建时间: 上午9:42. * 修改历史: * ----------------------------------------------- */ public class TaskKit { private static ScheduledThreadPoolExecutor taskScheduler = new ScheduledThreadPoolExecutor(getBestPoolSize()); private static List<Timer> timerList = new ArrayList<Timer>(); /** * 测试 * @param args */ public static void main(String[] args){ System.out.println("开始启动"); TaskKit.scheduleAtFixedRate(new Runnable(){ @Override public void run() { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(format.format(new Date())+" , 一直测试......"); } },10); System.out.println("启动完成"); } /** * 立即启动,并以固定的频率来运行任务。后续任务的启动时间不受前次任务延时影响。 * * @param task 具体待执行的任务 * @param periodSeconds 每次执行任务的间隔时间(单位秒) */ public static ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long periodSeconds) { return scheduleAtFixedRate(task, 0, periodSeconds, TimeUnit.SECONDS); } /** * 在指定的延时之后开始以固定的频率来运行任务。后续任务的启动时间不受前次任务延时影响。 * * @param task 具体待执行的任务 * @param initialDelay 首次执行任务的延时时间 * @param periodSeconds 每次执行任务的间隔时间(单位秒) * @param unit 时间单位 */ public static ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long initialDelay, long periodSeconds, TimeUnit unit) { return taskScheduler.scheduleAtFixedRate(task, initialDelay, periodSeconds, unit); } /** * 在指定的时间点开始以固定的频率运行任务。后续任务的启动时间不受前次任务延时影响。 * * @param task 具体待执行的任务 * @param startTime 首次运行的时间点,支持 "yyyy-MM-dd HH:mm:ss" 格式 * @param period 每次执行任务的间隔时间 * @param unit 时间单位 */ public static void scheduleAtFixedRate(Runnable task, String startTime, long period, TimeUnit unit) throws ParseException { //Date dt = DateKit.dateFormat(startTime, "yyyy-MM-dd HH:mm:ss"); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date dt = format.parse(startTime); scheduleAtFixedRate(task, dt, period, unit); } /** * 在指定的时间点开始以固定的频率运行任务。后续任务的启动时间不受前次任务延时影响。 * * @param task 具体待执行的任务 * @param startTime 首次运行的时间点 * @param period 每次执行任务的间隔时间 * @param unit 时间单位 */ public static void scheduleAtFixedRate(final Runnable task, Date startTime, final long period, final TimeUnit unit) { final Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { taskScheduler.scheduleAtFixedRate(task, 0, period, unit); timer.cancel(); timerList.remove(timer); } }, startTime); timerList.add(timer); } /** * 立即启动,两次任务间保持固定的时间间隔 * * @param task 具体待执行的任务 * @param periodSeconds 两次任务的间隔时间(单位秒) */ public static ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long periodSeconds) { return scheduleWithFixedDelay(task, 0, periodSeconds, TimeUnit.SECONDS); } /** * 在指定的延时之后启动,两次任务间保持固定的时间间隔 * * @param task 具体待执行的任务 * @param initialDelay 首次执行任务的延时时间 * @param period 两次任务的间隔时间(单位秒) * @param unit 时间单位 */ public static ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long initialDelay, long period, TimeUnit unit) { return taskScheduler.scheduleWithFixedDelay(task, initialDelay, period, unit); } /** * 在指定的时间点启动,两次任务间保持固定的时间间隔 * * @param task 具体待执行的任务 * @param startTime 首次运行的时间点,支持 "yyyy-MM-dd HH:mm:ss" 格式 * @param period 两次任务的间隔时间 * @param unit 时间单位 */ public static void scheduleWithFixedDelay(Runnable task, String startTime, long period, TimeUnit unit) throws ParseException { //Date dt = DateKit.dateFormat(startTime, "yyyy-MM-dd HH:mm:ss"); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date dt = format.parse(startTime); scheduleWithFixedDelay(task, dt, period, unit); } /** * 在指定的时间点启动,两次任务间保持固定的时间间隔 * * @param task 具体待执行的任务 * @param startTime 首次运行的时间点 * @param period 两次任务的间隔时间 * @param unit 时间单位 */ public static void scheduleWithFixedDelay(final Runnable task, Date startTime, final long period, final TimeUnit unit) { final Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { taskScheduler.scheduleWithFixedDelay(task, 0, period, unit); timer.cancel(); timerList.remove(timer); } }, startTime); timerList.add(timer); } /** * 调整线程池大小 * * @param threadPoolSize */ public static void resizeThreadPool(int threadPoolSize) { taskScheduler.setCorePoolSize(threadPoolSize); } /** * 返回定时任务线程池,可做更高级的应用 * * @return */ public static ScheduledThreadPoolExecutor getTaskScheduler() { return taskScheduler; } /** * 关闭定时任务服务 * <p>系统关闭时可调用此方法终止正在执行的定时任务,一旦关闭后不允许再向线程池中添加任务,否则会报RejectedExecutionException异常</p> */ public static void depose() { int timerNum = timerList.size(); //清除Timer synchronized (timerList) { for (Timer t : timerList) t.cancel(); timerList.clear(); } List<Runnable> awaitingExecution = taskScheduler.shutdownNow(); System.out.println("关闭定时任务服务"); } /** * 重启动定时任务服务 */ public static void reset() { depose(); taskScheduler = new ScheduledThreadPoolExecutor(getBestPoolSize()); } /** * 根据 Java 虚拟机可用处理器数目返回最佳的线程数。<br> * 最佳的线程数 = CPU可用核心数 / (1 - 阻塞系数),其中阻塞系数这里设为0.9 */ private static int getBestPoolSize() { try { // JVM可用处理器的个数 final int cores = Runtime.getRuntime().availableProcessors(); // 最佳的线程数 = CPU可用核心数 / (1 - 阻塞系数) // TODO 阻塞系数是不是需要有个setter方法能让使用者自由设置呢? return (int) (cores / (1 - 0.9)); } catch (Throwable e) { // 异常发生时姑且返回10个任务线程池 return 10; } } } |