本文是学习悟空老师的视频教程线程八大核心基础后所做的心得笔记,想更加具体了解其中知识的小伙伴可以前往慕课网悟空老师的课程中进行学习
Java实现多线程的方法(2种)
- 实现Runnable接口
- 继承Thread类
本质是两种,同时原理上两种本质是一样的
代码的实现n+
结论依据:参考Java官方文档
参考文档:https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
两种实现方法示例:
package com.hbj.learning.threadcoreknowledge.createthreads;
/**
* 用Runnable方式创建线程(使用该方法更好)
*
* @author hbj
* @date 2019/10/24 14:19
*/
public 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方法实现线程");
}
}
package com.hbj.learning.threadcoreknowledge.createthreads;
/**
* 用Thread方式实现线程
*
* @author hbj
* @date 2019/10/24 14:22
*/
public class ThreadStyle extends Thread {
@Override
public void run() {
System.out.println("使用Thread方式实现线程");
}
public static void main(String[] args) {
new ThreadStyle().start();
}
}
两种方法的对比/使用Thread创建线程方法的缺点:(优先使用Runnable方法创建线程)
- 未解耦-Thread的创建方法和编程中的业务代码高耦合(代码架构角度 线程部分的代码+业务部分的代码 解耦 只需要考虑run方法里面的内容)
- 资源浪费-Thread方法每次创建都需要新建线程(创建,运行,销毁)一套完整的流程,而Runnable方法可以利用线程池等(反复利用创建的线程,资源消耗较小)
- 不能多继承-Java不能多继承,而该方法继承Thread方法后不能再继承其他类
共同点:
- 都是重写run函数
- 最终都是调用start方法来新建线程
准确的描述:
创建线程的方法只有一个(即构造Thread类),而实现线程的执行单元(重写run函数)有两种方法
- 实现Runnable接口的run方法,并将它作为target传给Thread(最终调用target.run方法)
- 重写Thread的run方法
假如同时使用两种方法,会有什么结果??
package com.hbj.learning.threadcoreknowledge.createthreads;
/**
* 同时使用Runnable和Thread方法创建线程
*
* @author hbj
* @date 2019/10/24 15:31
*/
public class BothRunnableThread {
public static void main(String[] args) {
new Thread(new Runnable() {
// 传入Runnable对象
@Override
public void run() {
System.out.println("我来自Runnable");
}
}) {
// 重写了Thread类的run方法
// 覆盖了原来的三行代码,导致上面的Runnable传参失效
// @Override
// public void run() {
// if (target != null) {
// target.run();
// }
// }
@Override
public void run() {
System.out.println("我来自Thread");
}
}.start();
}
}
执行结果:(原因:从面向对象的角度分析,具体见代码中的注释)
我来自Thread
- 线程池创建线程不算是一种创建线程地方法
- FutureTask和Callable创建线程不算是一种创建线程地方法
所有类似的创建线程的方法,都只是包装了new Thread(),创建线程的方法仅有上面陈述的两个
网友评论