线程的生命周期
新建状态
通过 new 创建线程对象, 只是在堆中开辟了一块空间, 线程并没有开始执行
可运行状态
用线程对象调用 start() 方法
就绪状态
等待 CPU 调度, 线程并没有开始执行
运行状态
获得 CPU 的调度, 开始执行, 如果有多个 CPU, 允许多个线程并行执行
等待状态
同步锁调用 wait 方法, 把当前对象放到等待池中, 等待唤醒 notify
计时等待
sleep 方法, 进行休眠, 休眠过程中并不释放同步锁. 带参数的 wait 方法, 如果没有被其他线程唤醒, 就等待指定时间自动苏醒
阻塞状态
正在运行的线程因为某些原因放弃 CPU, 暂时停止运行, 就会进入阻塞状态. 此时 JVM 不会给线程分配 CPU, 直到线程重新进入就绪状态, 才有机会转到运行状态. 阻塞状态只能先进入就绪状态, 不能直接进入运行状态, 阻塞状态的两种情况:
当 A 线程处于运行过程时, 试图获取同步锁时, 却被 B 线程获取. 此时 JVM 把当前 A 线程存到对象的锁池中, A 线程进入阻塞状态.
当线程处于运行过程时, 发出了 IO 请求时, 此时进入阻塞状态.
终止状态
通常称为死亡状态, 表示线程终止
正常执行完 run 方法而退出 (正常死亡)
遇到异常而退出 (出现异常之后, 程序就会中断)(意外死亡).
联合线程
线程的 join 方法表示一个线程等待另一个线程完成后才执行. join 方法被调用之后, 线程对象处于阻塞状态.
- class Join extends Thread{
- public void run(){
- for(int i = 0; i < 50; i++){
- System.out.println("Join"+"--" + i);
- }
- }
- }
- public class JoinDemo {
- public static void main(String[] args) throws Exception {
- Join j = new Join();
- for(int i = 0;i < 50;i++){
- System.out.println("main" + "--" + i);
- if(i == 10){
- j.start();
- }
- if(i == 20){
- j.join();// 强制执行, 执行完该线程再执行主线程
- }
- }
- }
- }
后台线程
在后台运行的线程, 其目的是为其他线程提供服务, 也称为 "守护线程".JVM 的垃圾回收线程就是典型的后台线程. 若所有的前台线程都死亡, 后台线程自动死亡, 前台线程没有结束, 后台线程是不会结束的. 测试线程对象是否为后台线程: 使用 thread.isDaemon(). 前台线程创建的线程默认是前台线程, 可以通过 setDaenon(true) 方法设置为后台线程, 并且当且仅当后台线程创建的新线程时, 新线程是后台线程.
- public class DeamonDemo {
- public static void main(String[] args) {
- // 判断 main 线程是否后台线程
- // boolean b = Thread.currentThread().isDaemon();
- // System.out.println(b);
- // 设置 main 线程为后台线程, 报错, 线程一旦创建就不能修改为后台线程
- //Thread.currentThread().setDaemon(true);
- // 创建并启动 Demo 线程, 设置为后台线程
- /**
- * 此时 Demo 为守护线程, 当所有的前台线程都执行完毕后, 守护线程自动死亡
- * 在这会发现, 当主线程执行完毕后, 守护线程 Demo 没有执行完自己的方法都结束了
- * 但让也不一定守护线程立马就停止了, 也要有反应时间
- */
- Demo d = new Demo();
- d.setDaemon(true);
- d.start();
- for (int i = 0; i < 20; i++) {
- System.out.println("main" + "--" + i);
- }
- }
- }
- class Demo extends Thread{
- @Override
- public void run() {
- for(int i = 0;i < 50;i++){
- System.out.println("Demo" + "--" + i);
- }
- }
- }
线程的优先级
每个线程都有优先级, 优先级的高低只和线程获得执行机会的次数多少有关, 并非线程优先级越高的就一定先执行, 哪个线程的先运行取决于 CPU 的调度.
- /**
- * 线程的优先级
- * int getPriority() : 返回线程的优先级.
- * void setPriority(int newPriority) : 更改线程的优先级.
- */
- public class priority {
- @SuppressWarnings("static-access")
- public static void main(String[] args) {
- // 优先级的默认值为 5
- System.out.println(Thread.currentThread().getPriority());//5
- // 更改优先级 (优先级可以在线程创建之后更改)
- Thread.currentThread().setPriority(7);
- System.out.println(Thread.currentThread().getPriority());//7
- // 创建 A 线程, 查看 A 线程的优先级,
- A a = new A();
- a.start();
- System.out.println(a.getPriority());//7
- //Thread 类中也有三个常量
- System.out.println(a.MAX_PRIORITY);//10
- System.out.println(a.MIN_PRIORITY);//5
- System.out.println(a.NORM_PRIORITY);//1
- }
- }
- class A extends Thread{
- @Override
- public void run() {
- }
来源: https://www.cnblogs.com/tfper/p/9866328.html