Java 高并发编程与详解笔记(一)-- 初识 Java 线程

iBit程序猿 2020年09月10日 1,044次浏览

从今天开始撸汪文君的《Java 高并发编程详解(多线程与架构设计)》,做的笔记可能跟书上的目录有所不同,纯属按照自己的理解重新构造一下,今天主题 -- 初识 Java 线程。

快速认识线程

创建线程的方式

只有一种,构造 Thread 类。

实现线程的执行单元方式:

  • 重写 Thread 的 run 方法。
  • 实现 Runnable 接口的 run 方法,并将 Runnable 实例作为构造 Thread 的参数。

执行单元实现方式对应的设计模式

  • 模板设计模式

  • 策略设计模式

备注: 想了解更多的设计模式相关知识,可以参考上篇文章《图解设计模式-笔记》。

相关实现代码

重写 Thread 的 run 方法

public class ConcreteThread extends Thread {

    @Override
    public void run() {
        System.out.println(Thread.currentThread() +  " run");
    }

    public static void main(String[] args) {
        final ConcreteThread task = new ConcreteThread();
        task.start();
    }
}

实现 Runnable 接口

public class TicketWindowRunnable implements Runnable {

    /**
     *  索引位置
     */
    private int index = 1;

    /**
     * 定义最大值为50
     */
    private final static int MAX = 50;

    @Override
    public void run() {
        while (index <= MAX) {
            // 同步锁
            synchronized (this) {
                if (index <= MAX) {
                    System.out.println(Thread.currentThread() +  " 的号码是:" + (index++));
                }
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
    
    public static void main(String[] args) {
        final TicketWindowRunnable task = new TicketWindowRunnable();
        Thread window1 = new Thread(task, " 一号窗口 ");
        window1.start();
    }
}

观察线程工具

  • Jconsole

  • jstack

线程的生命周期

书本上的线程的生命周期图(下图),是不对的(应该是进程的生命周期图)。

应该更正为:

image.png

线程的生命周期可分为以下六个状态:

  • NEW: 还没开始执行的新创建的线程
  • RUNNABLE: 执行中或准备执行(等待调度)
  • BLOCKED:等待获取 Monitor 锁进入或重新进入同步块或方法
  • WAITING:无时间限制等待其他线程执行特定操作
  • TIMED_WAITING: 等待其他线程在指定时间内执行特定操作
  • TERMINATED: 执行完成

理解 Thread 的构造方法

Thread 构造函数

构造函数相关联的参数

  • String name: 线程名称
  • ThreadGroup group:线程组
  • Runnable target:执行单元
  • long stackSize:栈大小

线程命名

  • 构造 Thread 时指定名称
  • 在 Thread start() 调用之前通过 setName(String name) 指定名称

线程的父子关系

Thread 在初始化(init)时会指定当前线程为新线程的父线程。

相关结论:

  • 一个线程的创建肯定是由另一个线程完成的
  • 被创建的线程的父线程是创建它的线程

Thread 与 ThreadGroup 关系

构造一个线程的时候,如果没有显式地指定 ThreadGroup,那么它将会和父线程同属于一个 ThreadGroup。

Thread 与 Runnable 关系

  • Thread 负责线程本身相关的职责和控制
  • Runnable 则负责逻辑执行单元的部分

Thread 与 JVM 虚拟栈关系

todo:学习JVM的时候,在好好的理解一下

守护线程

若JVM 中没有非守护线程,不管有没有守护线程,JVM 进程都会退出。当你希望关闭某些线程的时候,或者退出 JVM 进程的时候,一些线程能够自动关闭,此时可以考虑用守护线程为你完成这样的工作。