线程简介
1.1 什么是线程
在理解什么是线程之前还要知道一个概念——进程。现代操作系统在运行一个java程序时,会为其创建一个进程,而现代操作系统调度的最小单元是线程,也叫轻量级进程(light weight process),在一个进程里面可以创建多个线程,这些线程都拥有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的内存变量。处理器在这些线程上高速切换,让使用者感觉得这些线程在同时运行。
一个Java程序从main()方法开始执行,看似只有一个线程,但实际上Java天生就是多线程,因为执行main()方法的是一个名称为main的线程。我们来看看一个普通的java线程包含哪些线程。
public class MultiThread {
public static void main(String[] args) {
// 获取Java线程管理 MXBean
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
// 获取线程和线程数堆栈信息,后两个参数为true则为获取同步的monitors和synchronize信息
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
// 遍历线程信息,仅打印线程ID和线程名称
for (ThreadInfo threadInfo : threadInfos) {
System.out.println("id:" + threadInfo.getThreadId() + "name:" + threadInfo.getThreadName());
}
}
}
运行结果:
id:6 name:Monitor Ctrl-Break
id:5 name:Attach Listener
id:4 name:Signal Dispatcher
id:3 name:Finalizer
id:2 name:Reference Handler
id:1 name:main
可以看到一个Java程序的运行是由main线程和多个线程一起组成的。
1.2 为什么用多线程
简单归结为以下几点:
- 更多的处理核心
随着处理器核心越来越多,而一个单线程程序在运行时只能使用一个核心处理,多核反而无法提升程序的执行效率。使用多线程技术,将计算逻辑分配到多核处理器核心,就会显著减少陈旭处理时间,提升程序执行效率。 - 更快的响应时间
在一些复杂的业务逻辑中,将数据一致性不强的操作派发给其他线程处理(也可使用消息队列),如生成订单快照,发送邮件等。缩短响应时间,提升用户体验。 - 更好的编程模式
Java为多线程程序提供了良好、考究并且一致的编程模型,使开发人员专注于问题的解决。
1.3 线程优先级
优先级高低决定了线程分配时间片的数量。现代操作系统基本采用时分的形式调度运行的线程,操作系统会分出一个个的时间片,线程会分配到若干时间片,当线程的时间片用完了就会发生线程调度,并等待下次分配。
在java中,通过Thread.setPriority(int)方法来修改优先级,默认优先级是5。(线程优先级不能作为线程正确性的依赖)
1.4 线程的状态
状态名称 | 说明 |
---|---|
NEW | 初始状态,线程被构建,但是还没有调用start()方法 |
RUNNABLE | 运行状态,Java线程将操作系统中的就绪和运行两种状态笼统的称作“运行中” |
BLOCKED | 阻塞状态,表示线程阻塞于锁 |
WAITING | 等待状态,表示线程进入等待状态,进入该状态表示当前线程需要等待其他线程做出一些特定动作(唤醒或中断) |
TIMED_WAITING | 超时等待状态,可以在指定时间自行唤醒 |
TERMINATED | 终止状态,表示当前线程已经执行完毕 |
线程在自身的生命周期中,并不是固定处在某个状态,而是随着代码的执行在不同的状态之间切换。
由图中可以看到,线程创建(初始化)之后,调用start()方法开始运行。当线程执行wait()方法之后,线程进入等待状态。进图等待状态的线程需要依靠其他线程的通知才能返回的运行状态,而超时等待状态只需要超时时间到达时就可以返回到运行状态。当线程代用同步方法死,在没有获取到锁的情况下,线程将会进入到阻塞状态。线程在执行Runnable的run()方法之后将会进入终止状态。
注: Java将操作系统中的运行和就绪两个状态合并成为运行状态。阻塞状态是线程阻塞在Synchronize关键字修饰的方法或代码块(获取锁)时的状态,但是阻塞在java.concurrent包中Lock接口线程的状态为等待状态,因为java.concurrent包中Lock接口对于阻塞的实现使用了LockSupport类中相关的方法。
结尾
本篇文章具体讲解了何为线程、使用多线程的好处,重点是线程的状态以及线程状态的变迁。希望对各位开发同学有用,欢迎大家留言探讨一起学习进步,共勉。