Java实现多线程有两种经常使用方法:继承Thread类和实现Runable接口。下面学习下两种方法的源码。
1.继承Thread类
这种方法实现多线程示例以下:java
class MyThread extends Thread{ @Override public void run(){ System.out.println("Hello thread"); } } public class ThreadPool { public static void main(String args[]){ MyThread myThread = new MyThread(); myThread.start(); } }
能够看出,这种方法先是继承Thread类,重写Thread类的run方法,要使用多线程时再调用start方法。以前一直有一个疑问,为何重写的是run方法,而调用的是start方法呢。run方法和start方法有什么关系呢?今天好好的研究下它们的关系。
点开start方法的源码,能够看到它的实现(为了看起来简洁,去掉注释了):算法
public synchronized void start() { if (threadStatus != 0) throw new IllegalThreadStateException(); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { } } }
从上面代码能够看出,start方法调用了start0方法,而点开start0能够看到下面这行代码设计模式
private native void start0();
start0方法被native修饰,是本地方法。查阅资料后发现JDK官方文档在start方法有这样的注释:
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread. 从这句话能够知道start方法调用start0方法,而start0则会经过JVM调用run方法。过程能够用下图表示:
能够看出这里使用了设计模式中的模板方法模式。模板方法模式定义:是在父类中定义算法的骨架,把具体实延迟到子类中去,能够在不改变一个算法的结构时可重定义该算法的某些步骤。真正实现逻辑的是run方法,所以使用者只须要重写run方法。多线程
2.实现Runnable接口
经过实现Runnable接口实现多线程代码示例以下:ide
class MyRunnable implements Runnable{ @Override public void run() { System.out.println("Hello Runnable!"); } } public class Demo { public static void main(String[] args) { new Thread(new MyRunnable()).start(); } }
先重写了Runnable接口的run方法,而后将Runnable实例用做构造Thread的参数。打开run方法的源码能够看到它的实现以下:学习
/** * If this thread was constructed using a separate * <code>Runnable</code> run object, then that * <code>Runnable</code> object's <code>run</code> method is called; * otherwise, this method does nothing and returns. * <p> * Subclasses of <code>Thread</code> should override this method. * * @see #start() * @see #stop() * @see #Thread(ThreadGroup, Runnable, String) */ @Override public void run() { if (target != null) { target.run(); } }
由上面的注释能够知道若是构造Thread时传递了Runnable,则会执行runnable的run方法。不然须要重写Thread类的run方法。this
经过上面的分析可知,不管仍是实现Runnable接口仍是继承Thread类,其实底层都是重写Thread的run方法,只不过第一种是直接重写Thread类的run方法的实现,第二种是在另外一个类中重写run方法,再传递到Thread中的run方法执行,也至关于重写了run方法(经过调用其余类中的run方法)。spa
像第二种方式其实用到了策略模式,把具体实现策略分离出来,再在执行的类中调用策略。线程
。设计