文章目录
多线程补充定时器并发和并行线程的生命周期
多线程补充
定时器
定时器介绍:
定时器是一种控制任务延时调用,或者周期调用的技术。
作用:闹钟、定时邮件发送。
定时器实现方式:
方式一:Timer
方式二: ScheduledExecutorService
Timer定时器构造器和方法如下:
构造器 | 说明 |
---|---|
public Timer() | 创建Timer定时器对象 |
public static void main(String[] args) { // 创建一个定时器任务 Timer timer = new Timer();}
方法 | 说明 |
---|---|
schedule(TimerTask task, long delay, long period) | 开启一个定时器,按照计划处理TimerTask任务 |
参数一: 延时执行的任务
参数二: 延迟的时间
参数三: 每隔多少时间执行一次(不传参数三表示只延迟执行一次)
public static void main(String[] args) { // 创建一个定时器任务 Timer timer = new Timer(); // 调用方法处理定时任务, 延迟执行三秒后每隔两秒执行一次 timer.schedule(new TimerTask() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "执行一次"); } }, 3000, 2000);}
Timer定时器的特点和存在的问题
Timer是单线程,处理多个任务按照顺序执行(意味着多个定时器会在一个线程中依次执行, 定时任务就会相互影响),存在延时与设置定时器的时间有出入。
可能因为其中的某个任务的异常使Timer线程死掉,从而影响后续任务执行。
ScheduledExecutorService定时器:
ScheduledExecutorService是 jdk1.5中引入了并发包,目的是为了弥补Timer的缺陷, ScheduledExecutorService内部为线程池。
Executors的方法 | 说明 |
---|---|
static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) | 得到线程池对象 |
ScheduledExecutorService的方法 | 说明 |
---|---|
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) | 周期调度方法 |
演示代码:
public static void main(String[] args) { // 创建ScheduledExecutorService线程池做定时器 ScheduledExecutorService pool = Executors.newScheduledThreadPool(3); // 开启定时任务 pool.scheduleAtFixedRate(new TimerTask() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "执行输出AAA"); } }, 0, 2, TimeUnit.SECONDS); // 多个定时器任务之间不会相互影响 pool.scheduleAtFixedRate(new TimerTask() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "执行输出BBB"); } }, 0, 2, TimeUnit.SECONDS);}
ScheduledExecutorService的优点:
基于线程池,某个任务的执行情况不会影响其他定时任务的执行。
并发和并行
并发与并行:
正在运行的程序(软件)就是一个独立的进程, 线程是属于进程的,多个线程其实是并发与并行同时进行的。
并发的理解:
CPU同时处理线程的数量有限。
CPU会轮流为系统的每个线程服务,由于CPU切换的速度很快,给我们的感觉这些线程在同时执行,这就是并发。
并行的理解:
在同一个时刻上,有多个线程真正的被CPU同时处理并执行。
线程的生命周期
线程的状态:
线程的状态:也就是线程从生到死的过程,以及中间经历的各种状态及状态转换。
理解线程的状态有利于提升并发编程的理解能力。
Java线程的状态:
Java总共定义了6种状态
6种状态都定义在Thread类的内部枚举类中, 如下:
public class Thread{...public enum State {NEW,RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED;}...}
线程中6种状态相互转换如下:
线程状态 | 描述 |
---|---|
NEW(新建) | 线程刚被创建,但是并未启动。 |
Runnable(可运行) | 线程已经调用了start()等待CPU调度 |
Blocked(锁阻塞) | 线程在执行的时候未竞争到锁对象,则该线程进入Blocked状态; |
Waiting(无限等待) | 一个线程进入Waiting状态,另一个线程调用notify或者notifyAll方法才能够唤醒 |
Timed Waiting(计时等待) | 同waiting状态,有几个方法有超时参数,调用他们将进入Timed Waiting状态。带有超时参数的常用方法有Thread.sleep 、Object.wait。 |
Teminated(被终止) | 因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。 |