1、模板设计模式
首先我们查看Thread类start方法的源码
/**
* Causes this thread to begin execution; the Java Virtual Machine
* calls the <code>run</code> method of this thread.
* <p>
* The result is that two threads are running concurrently: the
* current thread (which returns from the call to the
* <code>start</code> method) and the other thread (which executes its
* <code>run</code> method).
* <p>
* It is never legal to start a thread more than once.
* In particular, a thread may not be restarted once it has completed
* execution.
*
* @exception IllegalThreadStateException if the thread was already
* started.
* @see #run()
* @see #stop()
*/
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
通过源码查看Thread里面有几点需要注意
- 线程在创建时其中有一个属性threadStatus为0
- 线程无法重复进行start,否则会抛出IllegalThreadStateException异常
start方法前面有一个注释
英文大意是在开始运行线程时会调用run方法,但我们通过源码阅读后发现其中并没有调用run方法,那就只能是在JNI方法中start0中所调用。
Thread方法中的run方法源码如下
@Override
public void run() {
if (target != null) {
target.run();
}
}
如果我们直接使用默认构造方法进行创建并且没有重写run方法的话,这里看相当于是一个空方法
像Thread里面的这种用法的话,父类实现算法的大致结构,具体的逻辑实现代码由子类来实现,这便是一种模板设计模式的运用
2、策略设计模式
先看Runnable接口的源码
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
根据源码查看Runnable接口只定义了一个名字为run的方法,同时查看Thread源码也实现了Runnable接口
public
class Thread implements Runnable {
/* Make sure registerNatives is the first thing <clinit> does. */
private static native void registerNatives();
static {
registerNatives();
}
......
/**
* Allocates a new {@code Thread} object. This constructor has the same
* effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
* {@code (null, target, gname)}, where {@code gname} is a newly generated
* name. Automatically generated names are of the form
* {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
*
* @param target
* the object whose {@code run} method is invoked when this thread
* is started. If {@code null}, this classes {@code run} method does
* nothing.
*/
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
......
@Override
public void run() {
if (target != null) {
target.run();
}
}
......
}
在源码中我选取了以Runnable为参数的一个方法,我们通过会说创建线程有两种方法:一个是继承Thread重写run方法,一个是实现Runnable接口重写run方法;其实这种说法是不严谨的,第二种方法实际上是以实现Runnable接口的对象为参构建的Thread对象
像这种Thread与Runnable的关系类似于策略模式的运用,将线程的控制本身以及业务逻辑的处理完全隔离开来