从今天开始撸汪文君的《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
线程的生命周期
书本上的线程的生命周期图(下图),是不对的(应该是进程的生命周期图)。
应该更正为:
线程的生命周期可分为以下六个状态:
- 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 进程的时候,一些线程能够自动关闭,此时可以考虑用守护线程为你完成这样的工作。