Java多线程学习--14

说明:参考《Java多线程核心技术》

10、Timer定时器

Time类的主要作用是设置计划任务,但封装任务的类却是TimerTask类,执行计划任务的的代码放入TimerTask的子类中。TimerTask是一个抽象类。

1、执行一次某一任务:执行任务的时间晚于当前时间–在未来执行的效果

schedule(TimerTask task, Date time):

public class MyTask extends TimerTask {
    @Override
    public void run() {
        System.out.println("task is ok, time is " + new Date().toString());
    }
}
public class MyTaskTest {
    public static void main(String[] args) {
        System.out.println("current time is " + new Date());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 10);
        Date runDate = calendar.getTime();

        MyTask task = new MyTask();
        Timer timer = new Timer();
        timer.schedule(task, runDate);
    }
}
/**
 current time is Wed Jan 09 22:50:36 CST 2019
 task is ok, time is Wed Jan 09 22:50:46 CST 2019
 */

Timer源码:

/**Creates a new timer.  The associated thread does <i>not</i>
    Thread #setDaemon run as a daemon}*/  
public Timer() {
        this("Timer-" + serialNumber());
    }

可见:创建了一个Timer就是启动一个新的线程,那么这个信封线程并不是守护线程,一直在运行。

Timer timer = new Timer(true);

这是一个守护线程,运行完就消失。

2、计划时间早于当前时间–提前运行的效果

// 提前执行
calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) - 10);

TimeTask以队列的方式一个一个被顺序执行的。
源码:

public abstract class TimerTask implements Runnable{

方法schedule(TimerTask task, Date fiertTime, long period):在指定的日期之后按照指定间隔周期,无限循环的执行某一任务。

3、在未来执行:计划时间晚于当前时间
public class MyScheduleTask extends TimerTask{
    @Override
    public void run() {
        System.out.println("task is ok, time is " + new Date());
    }
}
public class MyScheduleTest {
    public static void main(String[] args) {
        System.out.println("currentTime is " + new Date());

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 10);
        Date runDate = calendar.getTime();
        System.out.println("schedule time is " + runDate);
        MyScheduleTask task = new MyScheduleTask();
        Timer timer = new Timer();
        timer.schedule(task, runDate, 4000);
    }
}
/**
 currentTime is Wed Jan 09 23:24:26 CST 2019
 schedule time is Wed Jan 09 23:24:36 CST 2019
 task is ok, time is Wed Jan 09 23:24:36 CST 2019
 task is ok, time is Wed Jan 09 23:24:40 CST 2019
 task is ok, time is Wed Jan 09 23:24:44 CST 2019
 task is ok, time is Wed Jan 09 23:24:48 CST 2019
 ...
 */

提前执行: 计划时间早于当前时间:如果计划时间早于当前时间,则立即执行。

// 提前执行
calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) - 10);

schedule源码:

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) {
        if (time < 0)
            throw new IllegalArgumentException("Illegal execution time.");

        // Constrain value of period sufficiently to prevent numeric
        // overflow while still being effectively infinitely large.
        if (Math.abs(period) > (Long.MAX_VALUE >> 1))
            period >>= 1;

        synchronized(queue) {  //private final TaskQueue queue = new TaskQueue();
            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();
        }
    }

cancel()方法:将自身从任务队列中进行清除,其他任务不受影响:
TimerTask中的cancel源码:

 public boolean cancel() {
        synchronized(lock) {
            boolean result = (state == SCHEDULED);
            state = CANCELLED;  // 清除当前的任务
            return result;
        }
    }

Timer中的cancel的源码:

 public void cancel() {
        synchronized(queue) {
            thread.newTasksMayBeScheduled = false;
            queue.clear();
            queue.notify();  // In case queue was already empty.
        }
    }
void clear() {  // 清除所有的任务
        // Null out task references to prevent memory leak
        for (int i=1; i<=size; i++)
            queue[i] = null;

        size = 0;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值