1、多线程有多少种创建方式呢?
一共有两种创建方式,在Oracle官方文档也有提及到。传送:http://tool.oschina.net/apidocs/apidoc?api=jdk-zh
2、使用Runnable接口创建多线程。
/** * @data 2019/11/8 - 下午3:39 * 描述:用Runnable方法实现线程 * */ class RunnableStyle implements Runnable { public static void main(String[] args) { Thread thread = new Thread(new RunnableStyle()); thread.start(); } @Override public void run() { System.out.println("使用Runnable方法实现线程"); } }
3、继承Thread类创建线程
/** * @data 2019/11/8 - 下午3:00 * 描述:用Thread方法实现线程 */ public class ThreadStyle extends Thread { @Override public void run() { System.out.println("使用Thread方法实现线程"); } public static void main(String[] args) { new ThreadStyle().start(); } }
4、若同时使用两种方式创建线程,会发生什么变化呢?上代码
/** * @data 2019/11/8 - 下午3:39 * 描述:同时使用两种方法实现线程 */ public class BothRunnableThread { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { System.out.println("这是Runnable方法"); } }){ @Override public void run() { System.out.println("这是Thread方法"); } }.start(); } }
结果:
原因:
翻开Thread类源码关于run方法:
target就是创建Thread传入进来的参数(实现Runnable接口的对象),通过源码就是说:
一、如果传进来参数(就是实现Runnable接口的对象),就执行该对象的run方法
二、若没有传进来参数,也就是通过继承Thread类来创建线程,子类会重写run方法,所以执行的是重新写的run方法
所以说,当两个方法同时进行时,即使传进来实现Runnable接口的对象了,但该Thread重写了run方法,破坏了之前run方法的内容,执行的是继承Thread方法里面的新run方法内容。
5、推荐使用实现Runnable接口来创建多线程。
- 从代码架构上看,执行具体任务(run方法实体)应该与创建和运行线程的机制(Thread类)解耦,用实现Runnable接口对象可以实现。
- 使用继承Thread方法创建,每次创建一个任务,就是需要创建一个独立的线程,这样太损耗资源了,而是用Runnable和线程池就可以大大减少这样的损耗。
- 因为java不支持多继承,如果继承了Thread类,就影响之后的扩展需求了。
综上,推荐使用实现Runnable接口来创建线程。
6、总结
到底创建多线程有多少种方法呢!
从不同的角度有不同的回答。
典型的回答就是两种,继承Thread父类和实现Runnable接口,两种方法。
从原理上看,这两种方法其实影响的是Thread的run方法,所以就是我们只能通过新建Thread类一个方式创建线程,两个方式来定义run真正执行的内容。
从网上看到的有三种四种创建的线程的方法,比如线程池、定时器等等,深究其内部源码,不就是我们讨论两个方法的包装而已。