多线程应用:定时器

 一. 定时器

定时器(定时任务)

  • 定时器是一种控制任务延时调用,或者周期调用的技术。
  • 作用:闹钟、定时邮件发送。

定时器的实现方式

  • 方式一:Timer
  • 方式二:ScheduledExecutorService

二. Timer定时器

  • TimerTask继承了Runnable:所以TimerTask是线程任务类 

 

 2.1 Timer定时器的实现

package com.gch.d8_timer;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
   目标:Timer定时器的使用和了解
 */
public class TimerDemo1 {
    public static void main(String[] args) {
        // 1.创建Timer定时器
        Timer timer = new Timer(); // 定时器本身就是一个单线程。
        // 2.调用方法,处理定时任务
        timer.schedule(new TimerTask() {
            @Override
            public void run() { // 由定时器线程来调的
                System.out.println(Thread.currentThread().getName() + "执行一次!" 
+ new Date().toLocaleString());
            }  // 第一次执行 / 启动后首先延迟两秒执行,然后每隔三秒执行一次
        },2000,3000);
    }
}

 2.2 Timer定时器的特点和存在的问题

  1. 问题1:Timer是单线程,处理多个任务按照顺序执行,存在延时与设置定时器的时间有出入
  • 因为Timer是单线程,某些任务忙,其他任务受到干扰,因为其他任务要等它处理完才执行,比如这里,A,B都是每隔两秒执行一次,但是执行到A的时候线程休眠了5秒,导致B已经过了2s的执行周期但因为线程在休眠无法执行,只能线程过了5s休眠才执行B
package com.gch.d8_timer;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
   目标:Timer定时器存在的问题
   问题1:Timer是单线程,处理多个任务按照顺序执行,存在延时与设置定时器的时间有出入
   因为Timer是单线程,某些任务忙,其他任务受到干扰,因为其他任务要等它处理完才执行
   比如这里,A,B都是每隔两秒执行一次,但是执行到A的时候线程休眠了5秒,导致B已经过了2s的执行周期但因为线程在休眠无法执行,只能线程过了5s休眠才执行B
 */
public class TimerDemo2 {
    public static void main(String[] args) {
        // 1.创建Timer定时器
        Timer timer = new Timer(); // 定时器本身就是一个单线程。
        // 2.调用方法,处理定时任务
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行A!" + new Date().toLocaleString());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            } // 启动后直接执行,然后每隔两秒执行一次
        },0,2000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行B!" + new Date().toLocaleString());
            }
        },0,2000);
    }
}

问题二:可能因为其中的某个任务的异常使Timer线程死掉,从而影响后续任务执行。

  • 比如这个程序要执行A,B,C三个任务,但是执行到B的时候程序出现异常,导致Timer线程直接挂掉,影响C的执行,导致整个任务全部挂掉。
package com.gch.d8_timer;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
   Timer定时器存在的问题
   问题二:可能因为其中的某个任务的异常使Timer线程死掉,从而影响后续任务执行。
   比如这个程序要执行A,B,C三个任务,但是执行到B的时候程序出现异常,导致Timer线程直接挂掉,影响C的执行
 */
public class TimerDemo3 {
    public static void main(String[] args) {
        // 1.创建Timer定时器
        Timer timer = new Timer(); // 定时器本身就是一个单线程。
        // 2.调用方法,处理定时任务
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行A!" + new Date().toLocaleString());
            } // 启动后直接执行,然后每隔两秒执行一次
        },0,2000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行B!" + new Date().toLocaleString());
                System.out.println(10 / 0); // 出现算术异常,Timer线程直接挂掉,影响后续任务执行
            }
        },0,2000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行C!" + new Date().toLocaleString());
            }
        },0,3000);

    }
}

  •  结论:开发中一般不会去用Timer做定时器!

三. ScheduledExecutorService定时器

  • ScheduledExecutorService它可以用多个线程去处理多个任务,这样即使某一个线程挂掉了也不会影响其他线程的执行。
  • 线程池必然是高级的。

package com.gch.d8_timer;

import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 目标:ScheduledExecutorService定时器的了解与使用
 */
public class ScheduledExecutorServiceDemo4 {
    public static void main(String[] args) {
        // 1.创建ScheduledExecutorService线程池,做定时器
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);

        // 2.开启定时任务
        // 以固定速率来执行
        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行输出A   " + new Date().toLocaleString());
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },0,2000, TimeUnit.MILLISECONDS);

        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(10 / 0); // 有异常,B不执行
                System.out.println(Thread.currentThread().getName() + "执行输出B   " + new Date().toLocaleString());
            }
        },0,2000, TimeUnit.MILLISECONDS);


        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行输出C   " + new Date().toLocaleString());
            }
        },0,2000, TimeUnit.MILLISECONDS);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/4339.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

APT、对称加密、非对称加密、SSL工作过程技术的介绍

1. APT的简单介绍APT全称:Advanced Persistent Threat 高级可持续威胁攻击。指的是某组织对特定对象展开持续有效的攻击活动。这种攻击活动具有极强的隐蔽性和针对性,通常会运用受感染的各种介质,供应链和社会工程学等手段,实施先…

【Vue全家桶】细说slot

【Vue全家桶】细说slot 文章目录【Vue全家桶】细说slot前言一、认识插槽Slot1.1 插槽的基本使用二、插槽的使用2.1 默认内容2.2 剧名插槽2.3 作用域插槽前言 我们已经了解到组件能够接收任意类型的 JavaScript 值作为 props,但组件要如何接收模板内容呢?…

【翻译】使用Go生成一个随机字符串(密码)

来源: Generate a random string (password) YourBasic Go https://yourbasic.org/golang/generate-random-string/ Random string 随机字符串 This code generates a random string of numbers and characters from the Swedish alphabet (which includes the non…

Linux内核查询

使用uname命令查找Linux内核 uname是用于获取系统信息的Linux命令。您也可以使用它来确定您使用的是32位还是64位系统。 打开一个终端并使用以下命令: [linuxmilinux:~/www.xxx.com]$ uname -r 输出将类似于以下内容: 5.3.0-28-generic 这意味着您正在…

【CocosCreator入门】CocosCreator组件学习 | Sprite(精灵)组件

Cocos Creator 是一款流行的游戏开发引擎,具有丰富的组件和工具,其中 Sprite 组件是最常用的之一。Sprite 组件用于渲染 2D 图像,并提供了许多可配置的选项,如图像纹理、尺寸、位置、旋转等。在本文中,我们将深入探讨 …

如何成为一个优秀的产品经理?

通过本文您可以清楚地了解产品经理的角色和职责,教您如何摇身一变成为优秀的产品经理的技巧等。 一、什么是产品经理? 产品经理主要的职责在于确定客户需求、将产品或功能实现商业目标的最大化、将产品打造成最终成功的样子,并召集团队将这…

python接口自动化(二)--什么是接口测试、为什么要做接口测试(详解)

什么是接口测试 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。  一般来说,测试接…

【Qt】Qt单元测试详解(一):通过QtCreator创建测试工程

1、简述 Qt程序支持多种测试框架,其中QtCreator可以协助创建4种测试框架,分别是: Boost的测试框架——Boost.Test Google测试框架——GTest Qt测试框架——QTest Qt Quick测试框架——QtQuickTest其他框架需要自行创建:Catch2、CTest 2、QtCreator创建测试工程 2.1 创建…

jenkins+sonarqube+自动部署服务

一、jenkins 配置Pipeline 二、新建共享库执行脚本 共享库可以是一个普通的gitlab项目,目录结构如下 三、添加到共享库 Jenkins Dashboard–>系统管理–>系统配置–>Global Pipeline Libraries Name: 共享库名称,自定义即可; Defa…

从CNN到Transformer:基于PyTorch的遥感影像、无人机影像的地物分类、目标检测、语义分割和点云分类

我国高分辨率对地观测系统重大专项已全面启动,高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成,将成为保障国家安全的基础性和战略性资源。随着小卫星星座的普及,对地观测已具备多次以上的全球覆盖…

输出数组的长度-课后程序(JavaScript前端开发案例教程-黑马程序员编著-第3章-课后作业)

【案例3-5】输出数组的长度 一、案例描述 考核知识点 length()方法 练习目标 掌握length()方法获取数组长度。掌握数组的遍历。 需求分析 数组中保存五个学生的数学成绩,遍历数组分别获取每一个学生的数学成绩分数,用length()函数获取数组的长度。 案…

帝国CMS7.2/7.5火车头配置说明以及使用教程

一淘模板 56admin.com给大家写一个帝国cms火车头采集器配置的教程,由于录视频太麻烦,所以直接打字上图了,希望能帮助到小伙伴! 火车头简要来讲分为 3 个部分的配置:1、发布地址配置;2、文件保存地址与图片…

数据结构|AOE网活动的最早、最迟发生时间及关键路径问题

一些知识点: 整个活动的完成时间是AOE图中从始点到终点的最长路径的长度,这条路径称为关键路径。关键路径上的活动称作关键活动。 注意:关键路径不一定只有一条。 1.最早发生时间:从前往后,前驱结点到当前结点所需时…

SpringBoot使用详解

概念 Spring Boot的启动器实际上就是一个依赖。这个依赖中包含了整个这个技术的相关jar包,还包含了这个技术的自动配置,以前绝大多数XML配置都不需要配置了。 如果是Spring自己封装的启动器的artifact id名字满足:spring-boot-starter-xxxx&…

Java分布式锁面试题

1.为什么需要分布式锁? public synchronized void test() {System.out.println("获取到锁"); } public void test2() {synchronized (Test.class) {System.out.println("获取到锁");} }假设我们把上述代码部署到多台服务器上,这个互斥锁还能生…

BPI-R3开发板 - atf编译

一. 获取源码 https://github.com/mtk-openwrt/arm-trusted-firmware 二. 编译步骤 和编译uboot一样,编译环境为ubuntu 18.04。交叉编译工具链我用的是openwrt编译生成的工具链,并设置到环境变量,如下: export PATH$PATH:/root/mt…

【大屏设计方案】

大屏设计方案一、非等比放大(填充满整个屏幕)目的屏幕比例大小和设计稿的差的不多目的屏幕比例大小和设计稿的差很多二、等比放大(比如16:9)解决方案之后就可以用rem了,有两种便利的方式:也可以用media 根据不同的屏幕…

膳食真菌在癌症免疫治疗中的作用: 从肠道微生物群的角度

谷禾健康 癌症是一种恶性肿瘤,它可以发生在人体的任何部位,包括肺、乳房、结肠、胃、肝、宫颈等。根据世界卫生组织的数据,全球每年有超过1800万人被诊断出患有癌症,其中约有1000万人死于癌症。癌症已成为全球范围内的主要健康问题…

@LoadBalanced注解原理

1.概述 使用注解就像是在代码中加入了一段魔法,让我们轻而易举的就实现了至关重要的功能。 就像LoadBalanced一样,将该注解使用在RestTemplate的Bean上,就可以实现负载均衡,就像下面这段代码: Configuration public…

新手UI设计师必读:火爆海外设计圈的设计资源!

Hello,各位好! 作为一名新手UI设计师,你是否无法完全搞清楚某些UI设计的基本原则和概念?你是否为使用哪款设计软件来开启你的设计之路而困扰?你是否想要在线学习设计排版、色彩搭配、形状和线条设计? 今天这…