创建线程
只有一种方法:构造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 线程终止:
Thread类中的模板设计模式
创建线程只有一种方法:**那就是构造 Thread 的类对象**
线程真正的执行逻辑在
run()
方法中,即 run() 方法是线程的执行单元
。Thread 类中的 run 和 start 就是比较典型的模板设计模式
:父类编写算法结构代码,子类实现逻辑细节。
public class Thread implements Runnable {
private Runnable target;
// 线程组
private ThreadGroup group;
// 线程状态
private volatile int threadStatus = 0;
// 开启线程的方法
public synchronized void start() {
/** Thread类对象第二次调用start()时,threadStatus不等于0,会抛出异常 */
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
boolean started = false;
try {
// 调用 run() 方法
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}
}
}
// native本地方法:调用run()方法
private native void start0();
@Override
public void run() {
/** 当没有使用runnable构造Thread时,Thread的run()方法本身是一个空实现 */
if (target != null) {
/** 当使用runnable构造Thread时,则调用重写Runnable接口中的run()方法逻辑 */
target.run();
}
// 否则则需要重写Thread类中的run()方法逻辑
}
}
Thread类中的策略设计模式
Thread类中的
策略模式
是通过引入 Runnable 接口将 线程的控制本身 和 业务逻辑 的运行分离开来,达到职责分明
、功能单一
的原则。即 Thread 负责线程本身相关的职责和控制,而 Runnable 则负责逻辑执行单元的部分。
public class Thread implements Runnable {
// Runnable接口对象
private Runnable target;
@Override
public void run() {
/** 当没有使用runnable构造Thread时,Thread的run()方法本身是一个空实现 */
if (target != null) {
/** 当使用runnable构造Thread时,则调用重写Runnable接口中的run()方法逻辑 */
target.run();
}
// 否则则需要重写Thread类中的run()方法逻辑
}
......
}
// Runnable接口仅包含线程执行单元逻辑
public interface Runnable {
public abstract void run();
}
调用 Thread 类的 public Thread(Runnable target)
构造方法时,Thread 中的 target 属性不为空,则执行重写 Runnable 接口中的 run() 执行单元。从而实现不同的 Thread 实例对象调用相同的 run() 执行单元逻辑,实现职责分明的目的。
public class TicketWindow implements Runnable {
public static void main(String[] args) {
TicketWindow window = new TicketWindow();
Thread window01 = new Thread(window, "一号");
Thread window02 = new Thread(window, "二号");
Thread window03 = new Thread(window, "三号");
Thread window04 = new Thread(window, "四号");
window01.start();
window02.start();
window03.start();
window04.start();
}
/** 共享资源:号码(不用static修饰)*/
private int index;
/** 当日限制50人 */
private static final int MAXNUM = 50;
/** 多个Thread实例共用一个run()方法执行单元 */
@Override
public void run() {
while (index < MAXNUM) {
System.out.println(Thread.currentThread() + " 当前号码为==>" + index++);
}
}
}