点击上方 "程序员小乐"关注, 星标或置顶一起成长
每天凌晨00点00分, 第一时间与你相约
每日英文
Be alike flower. Spread beauty and happiness wherever you stay; irrespective of your surroundings.
像花儿一样,无论身在何处,不管周遭环境如何,都依然潇洒的绽放自己的美丽,活出自己的精彩。
每日掏心话
人生尝尽了百味方觉甜美。偶尔隐匿的阳光,再来时更温暖;扑朔迷离的希望,出现时才令人惊喜。
来自:Fooisart | 责编:乐乐
链接:jianshu.com/p/e21eb60a2c41
往日回顾:史上首次!个人所得税退税来了!如何退?怎么操作?
正文
/** * 安排指定的任务task在指定的时间firstTime开始进行重复的固定速率period执行 * 每天中午12点都执行一次 * * @author Fooisart * Created on 21:46 14-01-2019 */public class TimerDemo { public static void main(String[] args) { Timer timer = new Timer(); Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 12);//控制小时 calendar.set(Calendar.MINUTE, 0);//控制分钟 calendar.set(Calendar.SECOND, 0);//控制秒 Date time = calendar.getTime();//执行任务时间为12:00:00 //每天定时12:00执行操作,每隔2秒执行一次 timer.schedule(new TimerTask() { @Override public void run() { System.out.println(new Date() + "执行任务。。。"); } }, time, 1000 * 2); }}
public void schedule(TimerTask task, Date firstTime, long period) { if (period <= 0) throw new IllegalArgumentException("Non-positive period."); sched(task, firstTime.getTime(), -period); }
private void sched(TimerTask task, long time, long period) { //省略非重点代码 synchronized(queue) { if (!thread.newTasksMayBeScheduled) throw new IllegalStateException("Timer already cancelled."); synchronized(task.lock) { if (task.state != TimerTask.VIRGIN) throw new IllegalStateException( "Task already scheduled or cancelled"); task.nextExecutionTime = time; task.period = period; task.state = TimerTask.SCHEDULED; } queue.add(task); if (queue.getMin() == task) queue.notify(); } }
给task设定了一些参数,类似于初始化task。这里还给它加了把锁,可以思考一下为甚要在此初始化?为何要加锁?(不是本文范畴,各位伙伴自行思考)
把初始化后的task加入到queue中。
/** * Adds a new task to the priority queue. */ void add(TimerTask task) { // Grow backing store if necessary if (size + 1 == queue.length) queue = Arrays.copyOf(queue, 2*queue.length); queue[++size] = task; fixUp(size); }
public Timer(String name) { thread.setName(name); thread.start(); }
public void run() { try { mainLoop(); } finally { // Someone killed this Thread, behave as if Timer cancelled synchronized(queue) { newTasksMayBeScheduled = false; queue.clear(); // Eliminate obsolete references } } }
继续进入mainLoop():
/** * The main timer loop. (See class comment.) */ private void mainLoop() { while (true) { try { TimerTask task; boolean taskFired; synchronized(queue) { //省略 long currentTime, executionTime; task = queue.getMin(); synchronized(task.lock) { if (task.state == TimerTask.CANCELLED) { queue.removeMin(); continue; // No action required, poll queue again } currentTime = System.currentTimeMillis(); executionTime = task.nextExecutionTime; if (taskFired = (executionTime<=currentTime)) { if (task.period == 0) { // Non-repeating, remove queue.removeMin(); task.state = TimerTask.EXECUTED; } else { // Repeating task, reschedule queue.rescheduleMin( task.period<0 ? currentTime - task.period : executionTime + task.period); } } } if (!taskFired) // Task hasn't yet fired; wait queue.wait(executionTime - currentTime); } if (taskFired) // Task fired; run it, holding no locks task.run(); } catch(InterruptedException e) { } } }
public class DelayTask implements Delayed { private Date startDate = new Date(); public DelayTask(Long delayMillions) { this.startDate.setTime(new Date().getTime() + delayMillions); } @Override public int compareTo(Delayed o) { long result = this.getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS); if (result < 0) { return -1; } else if (result > 0) { return 1; } else { return 0; } } @Override public long getDelay(TimeUnit unit) { Date now = new Date(); long diff = startDate.getTime() - now.getTime(); return unit.convert(diff, TimeUnit.MILLISECONDS); }} public static void main(String[] args) throws Exception { BlockingQueue<DelayTask> queue = new DelayQueue<>(); DelayTask delayTask = new DelayTask(1000 * 5L); queue.put(delayTask); while (queue.size()>0){ queue.take(); } }
构造DelayTask,其中的延迟时间是5秒
将任务放入队列
从队列中取任务
public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { for (;;) { E first = q.peek(); if (first == null) available.await(); else { long delay = first.getDelay(NANOSECONDS); if (delay <= 0) return q.poll(); first = null; // don't retain ref while waiting if (leader != null) available.await(); else { Thread thisThread = Thread.currentThread(); leader = thisThread; try { available.awaitNanos(delay); } finally { if (leader == thisThread) leader = null; } } } } } finally { if (leader == null && q.peek() != null) available.signal(); lock.unlock(); } }
欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,学习能力的提升上有新的认识,欢迎转发分享给更多人。
欢迎各位读者加入订阅号程序员小乐技术群,在后台回复“加群”或者“学习”即可。
猜你还想看
阿里、腾讯、百度、华为、京东最新面试题汇集
手把手教你 Netty 实现自定义协议!
一个简单的例子带你理解HashMap
【整理】Spring 常用注解!千万不要错过!
文章有问题?点此查看未经处理的缓存