多线程【定时器,并发、并行,线程生命周期】

定时器

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

定时器的实现方式

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

Timer定时器

在这里插入图片描述

/**
 * 目标;Timer定时器的使用和了解
 */
public class TimerDemo1 {
    public static void main(String[] args) {
        //1、创建Timer定时器
        Timer timer = new Timer();//定时器本身就是一个单线程
        timer.schedule(new TimerTask() {//匿名内部类形式 参数分别为:任务,延时时间3秒(启动之后隔多少秒开始执行),启动之后每隔2秒执行一次
            @Override
            public void run() {
                //逻辑
                System.out.println(Thread.currentThread().getName()+"执行一次~~~");
            }
        },3000,2000);
    }
}

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

  • 1、Timer是单线程,处理多个任务按照顺序执行,存在延时与设置定时器的时间有出入。
 timer.schedule(new TimerTask() {//匿名内部类形式
            /*一个线程执行两个任务*/

            @Override
            public void run() {
                //逻辑
                System.out.println(Thread.currentThread().getName() + "执行一次AAA~~~" + new Date());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, 0, 2000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                //逻辑
                System.out.println(Thread.currentThread().getName() + "执行一次BBB~~~" + new Date());
            }
        }, 0, 2000);
  • 2、可能因为其中的某个任务的异常使Timer线程死掉,从而影响后续任务执行。
 timer.schedule(new TimerTask() {
            @Override
            public void run() {
                //逻辑
                System.out.println(Thread.currentThread().getName() + "执行一次AAA~~~" + new Date());
                System.out.println(10/0);
            }
        }, 0, 2000);
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                //逻辑
                System.out.println(Thread.currentThread().getName() + "执行一次BBB~~~" + new Date());
            }
        }, 0, 2000);

如图:
在这里插入图片描述

因为是一个线程处理所有任务,当一个任务出现异常的时候,这个异常会抛给线程(因为是线程调用的),而线程没有捕获异常,它就把异常抛给虚拟机,虚拟机直接将程序干掉。

ScheduledExecutorService定时器

  • ScheduledExecutorService是 jdk1.5中引入了并发包,目的是为了弥补Timer的缺陷, ScheduledExecutorService内部为线程池。

在这里插入图片描述

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

public class TimerDemo2 {
    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()+"执行输出:AAA");
            }
        },0,2, TimeUnit.SECONDS);
    }
}

运行结果:

在这里插入图片描述

ScheduledExecutorService的优点

  • 1、基于线程池,某个任务的执行情况不会影响其他定时任务的执行
public class TimerDemo2 {
    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()+"执行输出:AAA"+new Date());
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },0,2, TimeUnit.SECONDS);

        /*现在是线程池,上边的线程被任务占用后,下边的任务还有其他的线程负责定时调度*/
        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行输出:BBB"+new Date());
            }
        },0,2, TimeUnit.SECONDS);
    }
}

运行结果:
在这里插入图片描述

pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行输出:BBB"+new Date());
                System.out.println(10/0);
            }
        },0,2, TimeUnit.SECONDS);
        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行输出:CCC"+new Date());
            }
        },0,2, TimeUnit.SECONDS);

运行结果:

在这里插入图片描述
并发与并行

  • 正在运行的程序(软件)就是一个独立的进程, 线程是属于进程的,多个线程其实是并发与并行同时进行的。

并发的理解:

  • CPU同时处理线程的数量有限。
  • CPU会轮询为系统的每个线程服务,由于CPU切换的速度很快,给我们的感觉这些线程在同时执行,这就是并发。

在这里插入图片描述

并行的理解:

  • 在同一个时刻上,同时有多个线程在被CPU处理并执行。

在这里插入图片描述
简单说说并发和并行的含义

  • 并发:CPU分时轮询的执行线程。
  • 并行:同一个时刻同时在执行,并行依赖于你CPU的逻辑处理器,比如你的CPU是16线程的,那意味着CPU可以同时处理16个线程。

线程的生命周期

人的状态
在这里插入图片描述

线程的状态

  • 线程的状态:也就是线程从生到死的过程,以及中间经历的各种状态及状态转换。
  • 理解线程的状态有利于提升并发编程的理解能力

Java线程的状态

  • Java总共定义了6种状态
  • 6种状态都定义在Thread类的内部枚举类中。

在这里插入图片描述

线程的6种状态互相转换

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值