【Java多线程】编程核心技术5 Lock

接着上一相关的那篇:应该有重合、就当复习了

1、计划时间早于当前时间,提前运行

2、TimerTask类的cancel()方法:将自身从任务队列中清除

3、Timer类的cancel方法:清空任务队列的全部任务

        如果该方法没有抢到锁,任务还是继续执行

4、schedule(TimerTask task ,long delay,long period)

        当前时间基础上延迟delay毫秒,再以period间隔无限次执行task任务

5、scheduleAtFixedRate(TimerTask task,Date firestTime,long period)

       同上一方法均会按顺序执行(不考虑非线程安全),两个方法区别在于不延迟的情况

          schedule:如执行任务的时间没有被延迟,下一次任务的执行时间参考上一次的开始时间

           scheduleAtFixedRate:如执行任务没有被延迟,下一次任务执行时间参考的是上一次的结束时间来计算 

       延迟:下一次任务执行时间均参考上一次结束时的时间来计算

      这是上篇博客里面的介绍,确认过三次眼神、是同一个意思


//同上,delay为第一次调度的时间:当前时间+时间片 实际时间 根据情况变动但是可能会被少调度*次
public void schedule(TimerTask task, Date firstTime, long period);
 
//在delay后开始调task,每经过period再次调度:计算出现在应该执行的时间+时间片 理论时间 时间不变减少漏掉调度的情况

     假设:task,打印执行时的时间。firstTime,是在20s之前的那个时间点。period是5s(每5秒执行一次),看这两个方法的表现:【

         1) schedule(TimerTask task, Date firstTime, long period) 执行效果: 执行时的firstTime是一个过去时间,所以定时任务启动时立马执行了1次。 然后就按照每隔5s执行一次的规则进行执行。

        2) scheduleAtFixedRate(TimerTask task, Date firstTime,long period) 执行效果: 执行时的firstTime是一个过去时间,它按照每隔5s执行一次的规则, 把从firstTime到currentTime这个时间段内,所有缺失的任务都给执行了(下面总结有细微) 然后再按照每隔5s执行一次的规则,继续执行当前时间之后的时间段内的任务。

        3) 总结: schedule方法的任务执行时间是和currentTime进行比较的,下一次的执行时间是:currentTime + period。 scheduleAtFixedRate方法的执行时间是和最初设定的firstTime进行比较的,下一次的执行时间是:firstTime + period。如果相加后的时间还没到当前时间,继续执行。直到加到的时间大于当前时间。 在源码上的区别,在Timer类的mainloop()方法中。

schedule、scheduleAtFixedRate:被延迟,下一次任务的执行时间以上一次任务“结束”时间为参考

public class Run2 {

    private static Timer timer = new Timer();

    private static  int runCount =0;

    static public class MyTask1 extends TimerTask{

        @Override
        public void run() {
            try {
                System.out.println("1 begin 运行了  时间为 "+new Date());
                Thread.sleep(5000);
                System.out.println("1 end  运行了 时间为"+new Date());
                runCount ++;
                if(runCount == 5){
                    timer.cancel();
                }
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        try {
            MyTask1 task1 = new MyTask1();
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateString = "2018-7-30 19:41:06";
            Date dateRef1 = sdf1.parse(dateString);
            System.out.println("字符串 时间"+dateRef1.toLocaleString()+"当前时间"+new Date().toLocaleString());
            timer.schedule(task1,dateRef1,2000);
        }catch (ParseException e){
            e.getErrorOffset();
        }
    }
}

scheduleAtFixedRate:会执行之前的任务,“补充性”追赶执行,schedule不追赶不补充、会漏

public class Run6 {

    private static Timer timer = new Timer();

    static public class MyTask1 extends TimerTask{

        @Override
        public void run() {
            System.out.println("1 begin "+new Date());
            System.out.println("1 end "+ new Date());
        }
    }

    public static void main(String[] args) {
        try{
            Run5.MyTask1 task1 = new Run5.MyTask1();
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateString1 = "2018-7-30 20:07:40";
            Date dateRef1 =sdf1.parse(dateString1);
            System.out.println("字符串1"+dateRef1.toLocaleString()+"当前时间"+new Date().toLocaleString());
            timer.scheduleAtFixedRate(task1,dateRef1,5000);
        }catch (ParseException e){
            e.printStackTrace();
        }
    }

}

猜你喜欢

转载自blog.csdn.net/ma15732625261/article/details/81280959