java的多线程实现方式_Java多线程_创建多线程的两种常用方式浅析

Java实现多线程有两种常用方法:继承Thread类和实现Runable接口。下面学习下两种方法的源码。

1.继承Thread类

这种方法实现多线程示例如下:

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方法。过程可以用下图表示:

9f059c34eb290c3724f86fc1ece8ee5a.png

可以看出这里使用了设计模式中的模板方法模式。模板方法模式定义:是在父类中定义算法的骨架,把具体实延迟到子类中去,可以在不改变一个算法的结构时可重定义该算法的某些步骤。真正实现逻辑的是run方法,因此使用者只需要重写run方法。

2.实现Runnable接口

通过实现Runnable接口实现多线程代码示例如下:

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

* Runnable run object, then that

* Runnable object's run method is called;

* otherwise, this method does nothing and returns.

*

* Subclasses of Thread 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方法。

通过上面的分析可知,无论还是实现Runnable接口还是继承Thread类,其实底层都是重写Thread的run方法,只不过第一种是直接重写Thread类的run方法的实现,第二种是在另一个类中重写run方法,再传递到Thread中的run方法执行,也相当于重写了run方法(通过调用其他类中的run方法)。

像第二种方式其实用到了策略模式,把具体实现策略分离出来,再在执行的类中调用策略。

41b1869a6665e939cdc0fe60be3b3e01.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值