Java 并发编程
为什么要使用并发编程 (多线程)
- 科技的发展, 越来越多的机器拥有更多的处理器核心
- 多线程可以带来更快的响应速度
- 更好的编程模型
什么是线程
首先我们所写的 Java EE 程序在启动后, 会开启一条进程来执行我们的代码. 而其中的每个逻辑处理, 就是由线程去完成的.
线程是现代操作系统所能调度的最小单元.
线程的优先级
在Java中, 我们可以通过 priority 属性来设置线程的优先级, 参数为 1 ~ 10 参数越大, 代表优先级越高, 默认的优先级为 5
而这一参数在不同的虚拟机上, 在不同的操作系统上都会有不同的表现, 甚至被忽略
知识点: 不能依赖此值来设计线程的优先顺序, 并没有绝对意义.
线程的状态
- 初始状态, 线程被构建, 没有调用start方法
- 运行状态, Java 将操作系统的线程"就绪"和"运行"状态统一称为"运行中"
- 阻塞状态, 线程处于阻塞时
- 等待状态, 线程进入等待状态, 此时需要等待其他线程一些动作(通知或中断)
- 超时等待状态, 此状态不同于等待状态是可以在一定时间内自动返回
- 终止状态, 表示该线程已经执行完毕
守护线程 Daemon
负责程序运行的一个支持性工作, 当虚拟机中不存在非 Daemon 线程的时候虚拟机将会退出.
可以通过 setDaemon(true)
来指定守护线程, 该参数必须在线程启动前设置, 启动后设置无效.
我来理解这个绕脑的家伙, 如果一个线程设置了 setDaemon(true)
, 那就说明他是一个支持线程, 如果没有人需要他的时候, 他自然也就跟着退出了, 否则就会一直存在. 与启动他的线程共存. 他只是用来配合的, 没人需要的时候即退出.
知识点 : 在守护线程中不能使用 try catch finally { doSomeThing} , 因为当主线程退出后, 守护线程会立即退出, 并不会执行 finally 代码块内容
线程的创建
child线程是由 parent 线程进行空间分配, 同时会集成 parent 线程的优先级、守护线程状态、可以继承 parent 线程的 ThreadLocal
建议:为自己创建的线程分配一个名字,不需要多响亮,为的是解决问题时更容易认出他
线程中断
线程中断是线程中的一个标识位, 他表示一个线程是否被中断。
通过调用线程的 interrupted()方法可以查看线程是否处于中断状态
线程间通信
通过锁对象的 wait() 方法来释放锁, 同时进入等待队列;
通过锁对象的 notify()方法来唤醒等待队列的一个元素进入阻塞队列;
通过岁对象的notifyAll() 方法来唤醒等待队列的全部元素进入阻塞队列;
当调用了锁对象的 wait() 方法, 从等待队列被唤醒, 并重新获取到锁时, 将从等待地方开始, 程序计数器+1 , 继续执行下一条指令.