创建线程 只有一种方法:构造Thread类对象。而 实现线程的执行单元 则有两种方式:一是重写Thread的run方法;二是实现Runnable接口中的run方法。但是二者有着本质的区别,即 Thread 类的 run() 方法是不能共享的,也就是说A线程不能把B线程的 run() 方法当做自己的执行单元。而通过同一个 Runnable 实例构造不同的 Thread 实例则很容易实现这一点。


线程:线程是程序执行的一个路径,一个进程包含多个线程。多核CPU支持 并行运行 ,单核CPU通过时间钟快速轮询调度实现 多线程运行

线程的生命周期

  • new 对象创建:使用 new 关键字创建 Thread 类对象,此时线程还未创建。
  • runnable 等待运行:Thread 对象调用 start() 方法,在JVM进程中创建了一个等待运行的线程,是否运行看CPU调度。
  • running 正在运行:
  • blocked 线程阻塞:
  • terminated 线程终止:

image.png

Thread类中的模板设计模式

创建线程只有一种方法:**那就是构造 Thread 的类对象**

线程真正的执行逻辑在 run() 方法中,即 run() 方法是线程的 执行单元 。Thread 类中的 runstart 就是比较典型的 模板设计模式父类编写算法结构代码,子类实现逻辑细节

  1. public class Thread implements Runnable {
  2. private Runnable target;
  3. // 线程组
  4. private ThreadGroup group;
  5. // 线程状态
  6. private volatile int threadStatus = 0;
  7. // 开启线程的方法
  8. public synchronized void start() {
  9. /** Thread类对象第二次调用start()时,threadStatus不等于0,会抛出异常 */
  10. if (threadStatus != 0)
  11. throw new IllegalThreadStateException();
  12. group.add(this);
  13. boolean started = false;
  14. try {
  15. // 调用 run() 方法
  16. start0();
  17. started = true;
  18. } finally {
  19. try {
  20. if (!started) {
  21. group.threadStartFailed(this);
  22. }
  23. } catch (Throwable ignore) {
  24. }
  25. }
  26. }
  27. // native本地方法:调用run()方法
  28. private native void start0();
  29. @Override
  30. public void run() {
  31. /** 当没有使用runnable构造Thread时,Thread的run()方法本身是一个空实现 */
  32. if (target != null) {
  33. /** 当使用runnable构造Thread时,则调用重写Runnable接口中的run()方法逻辑 */
  34. target.run();
  35. }
  36. // 否则则需要重写Thread类中的run()方法逻辑
  37. }
  38. }

Thread类中的策略设计模式

Thread类中的 策略模式 是通过引入 Runnable 接口将 线程的控制本身 业务逻辑 的运行分离开来,达到 职责分明功能单一 的原则。即 Thread 负责线程本身相关的职责和控制,而 Runnable 则负责逻辑执行单元的部分。

  1. public class Thread implements Runnable {
  2. // Runnable接口对象
  3. private Runnable target;
  4. @Override
  5. public void run() {
  6. /** 当没有使用runnable构造Thread时,Thread的run()方法本身是一个空实现 */
  7. if (target != null) {
  8. /** 当使用runnable构造Thread时,则调用重写Runnable接口中的run()方法逻辑 */
  9. target.run();
  10. }
  11. // 否则则需要重写Thread类中的run()方法逻辑
  12. }
  13. ......
  14. }
  15. // Runnable接口仅包含线程执行单元逻辑
  16. public interface Runnable {
  17. public abstract void run();
  18. }

调用 Thread 类的 public Thread(Runnable target) 构造方法时,Thread 中的 target 属性不为空,则执行重写 Runnable 接口中的 run() 执行单元。从而实现不同的 Thread 实例对象调用相同的 run() 执行单元逻辑,实现职责分明的目的。

  1. public class TicketWindow implements Runnable {
  2. public static void main(String[] args) {
  3. TicketWindow window = new TicketWindow();
  4. Thread window01 = new Thread(window, "一号");
  5. Thread window02 = new Thread(window, "二号");
  6. Thread window03 = new Thread(window, "三号");
  7. Thread window04 = new Thread(window, "四号");
  8. window01.start();
  9. window02.start();
  10. window03.start();
  11. window04.start();
  12. }
  13. /** 共享资源:号码(不用static修饰)*/
  14. private int index;
  15. /** 当日限制50人 */
  16. private static final int MAXNUM = 50;
  17. /** 多个Thread实例共用一个run()方法执行单元 */
  18. @Override
  19. public void run() {
  20. while (index < MAXNUM) {
  21. System.out.println(Thread.currentThread() + " 当前号码为==>" + index++);
  22. }
  23. }
  24. }