Java多线程 - 定时器-并发与并行-线程生命周期
Posted 学全栈的灌汤包
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程 - 定时器-并发与并行-线程生命周期相关的知识,希望对你有一定的参考价值。
文章目录
多线程补充
定时器
定时器介绍:
定时器是一种控制任务延时调用,或者周期调用的技术。
作用:闹钟、定时邮件发送。
定时器实现方式:
方式一: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方法而死亡。 |
6Java并发性和多线程-并发性与并行性
以下内容转自http://tutorials.jenkov.com/java-concurrency/concurrency-vs-parallelism.html(使用谷歌翻译):
术语并发和并行性通常用于多线程程序。但是,并发和并行性究竟是什么意思呢,它们是相同的术语还是什么?
简短的答案是“不”。它们不是相同的术语,尽管它们在表面上看起来非常相似。也花了我一些时间来终于找到并了解并发和并行性之间的区别。因此,我决定在这个Java并发教程中添加一个关于并发性与并行性的文本。
并发
并发意味着应用程序同时在多个任务上同时进行。那么如果计算机只有一个CPU,应用程序可能不会在同一时间在多个任务上进行进展 ,但是在应用程序内一次处理多个任务。在下一个开始之前,它不完全完成一项任务。
并行
并行性意味着应用程序将其任务分解成更小的子任务,可以并行处理,例如在多个CPU上同时进行处理。
并发性与并行性细节
正如你所看到的,并发性与应用程序如何处理它所处理的多个任务有关。应用程序可以在时间(顺序)处理一个任务或同时处理多个任务(并发)。
另一方面,并行性与应用程序如何处理每个单独的任务有关。应用程序可以从头到尾连续地处理任务,或将任务分解成可以并行完成的子任务。
你可以看到,应用程序可以是并发的,但不是并行的。这意味着它同时处理多个任务,但任务不会分解为子任务。
应用程序也可以是并行的,但不是并发的。这意味着应用程序一次只能在一个任务上工作,并且该任务被分解成可并行处理的子任务。
另外,应用程序既可以并发也不能并行。这意味着它一次只能执行一个任务,并且任务不会被分解为并行执行的子任务。
最后,一个应用程序也可以并发和并行,因为它同时在多个任务上工作,并且还将每个任务分解成子任务并行执行。但是,在这种情况下,并发和并行性的一些好处可能会丢失,因为计算机中的CPU已经保持合并繁忙,并发或并行性。结合它可能只会导致小的性能增益甚至性能损失。在盲目采用并行并行模型之前,请确保分析和测量。
以上是关于Java多线程 - 定时器-并发与并行-线程生命周期的主要内容,如果未能解决你的问题,请参考以下文章