线程

现代操作系统的最小操作单元

线程的状态

  • NEW: 初始状态,线程被构建,但是还没有调用start()方法
  • RUNABLE: 运行状态,就绪和运行中两种状态统称为’运行中’
  • BLOCKED: 阻塞状态
  • WAITING: 等待状态,表示线程进入等待状态.进入该状态表示当前线程需要等待其他线程做出一些特定动作(通知/中断)
  • TIME_WAITING: 超时等待状态,不同于WAITING,可以在指定时间自行返回
  • TERMINATED: 终止状态,表示当前线程已经执行完成

线程状态迁移

Daemon线程

Daemon线程是一种支持型线程,因为它主要被用作程序中后台调度以及支持性工作。这 意味着,当一个Java虚拟机中不存在非Daemon线程的时候,Java虚拟机将会退出。可以通过调 用Thread.setDaemon(true)将线程设置为Daemon线程

Daemon属性需要在启动线程之前设置,不能在启动线程之后设置,在构建Daemon线程时,不能依靠finally块中的内容来确保执行关闭或清理资源的逻辑,因为Daemon线程的finally块不一定能执行

构造线程

一个新构造的线程对象是由其parent线程来进行空间分配的

child线程继承了parent是否为Daemon、优先级和加载资源的contextClassLoader以及可继承的ThreadLocal,同时还会分配一个唯一的ID来标识这个child线程

启动线程

线程对象在初始化完成之后,调用start()方法就可以启动这个线程。线程start()方法的含义 是:当前线程(即parent线程)同步告知Java虚拟机,只要线程规划器空闲,应立即启动调用 start()方法的线程

启动一个线程前,最好为这个线程设置线程名称,因为这样在使用jstack分析程 序或者进行问题排查时,就会给开发人员提供一些提示,自定义的线程最好能够起个名字

线程间通信

对象虽然在共享内存中,但是为提升效率,各个线程间可能持有拷贝的共享对象.

应该使用volatile和synchronized关键字解决线程的拷贝对象问题

等待通知范式

等待方遵守规则

  • 获取对象锁
  • 条件不满足,则调用wait方法,被通知后仍要检查条件
  • 条件满足后执行对应逻辑
1
2
3
4
5
6
syncronized(lock){
while(!condition){
lock.wait();
}
do biz;
}

通知方遵守原则:

  • 获取对象的锁
  • 改变条件
  • 通知所有等待的线程
1
2
3
4
synchronized(lock){
change condition;
lock.notifyAll();
}

文章链接 https://fangzongzhou.github.io/2020/10/27/计算机/技术栈/Java/并发编程/线程/