目录
1、线程的状态
关于六种状态还是五种状态的讨论:https://www.zhihu.com/question/56494969/answer/154053599
在Java程序中,一个线程对象只能调用一次start()
方法启动新线程,并在新线程中执行run()
方法。一旦run()
方法执行完毕,线程就结束了。
新生 、 就绪 、运行、死亡、阻塞
- 新生 - New:新创建的线程,尚未执行;
- 运行 - Runnable:运行中的线程,正在执行
run()
方法的Java代码; - 阻塞 - Blocked:运行中的线程,因为某些操作被阻塞而挂起;
- 等待 - Waiting:运行中的线程,因为某些操作在等待中;
- 计时等待 - Timed Waiting:运行中的线程,因为执行
sleep()
方法正在计时等待; - 终止 - Terminated:线程已终止,因为
run()
方法执行完毕。
2、 线程终止的原因:
- 线程正常终止:
run()
方法执行到return
语句返回; - 线程意外终止:
run()
方法因为未捕获的异常导致线程终止; - 对某个线程的
Thread
实例调用stop()
方法强制终止(强烈不推荐使用)。
等待其他线程先运行,然后再运行当前线程:一个线程还可以等待另一个线程直到其运行结束。例如,main
线程在启动t
线程后,可以通过t.join()
等待t
线程结束后再继续运行:
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
System.out.println("hello");
});
System.out.println("start");
t.start();
t.join();
System.out.println("end");
}
}
当main
线程对线程对象t
调用join()
方法时,主线程将等待变量t
表示的线程运行结束,即join
就是指等待该线程结束,然后才继续往下执行自身线程。所以,上述代码打印顺序可以肯定是main
线程先打印start
,t
线程再打印hello
,main
线程最后再打印end
。如果t
线程已经结束,对实例t
调用join()
会立刻返回。此外,join(long)
的重载方法也可以指定一个等待时间,超过等待时间后就不再继续等待。
- 通过对另一个线程对象调用
join()
方法可以等待其执行结束; - 可以指定等待时间,超过等待时间线程仍然没有结束就不再等待;
- 对已经运行结束的线程调用
join()
方法会立刻返回。
可以参考这篇总结来理解join:https://blog.csdn.net/Longtermevolution/article/details/104458220