Thread 类和 Runnable 接口
先说结论,一般用Ruunable而不用Thread 。本文主要解决问题 。下面将从Thread、Runnable是什么、干什么的、两者优势在哪里三个问题来解释两者。
1、是什么
Runnable是接口,Thread是Runnable是Thread的实现类。换而言之,Runnable不止Thread一个实现类,而Thread只是Runnable的接口。
public class Thread implements Runnable {}
private Runnable target;
public Thread(Runnable target,String name){
init(null,target,name,0);
}
private void init(ThreadGroup g,Runnable target,String name,long stackSize){
...
this.target=target;
}
public void run(){
if(target!=null){
target.run();
}
}
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface {@code Runnable} is used
* to create a thread, starting the thread causes the object's
* {@code run} method to be called in that separately executing
* thread.
* <p>
* The general contract of the method {@code run} is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
2、干什么的?
- Thread对Runnable进行功能实现(如run() ),同时加入自己的功能。包括start()。 实现Runnable 和 继承Thread类是java实现多线程的两种方式,
3、优势(***)?
大多数情况下,如果只想重写 run() 方法,而不重写其他 Thread 方法,那么应使用 Runnable 接口。除非你有打算修改或增强类的基本行为的需要,否则不应为该类(Thread)创建子类。
由于我们一般用Runnable,就只写Runnable的优点了。
- 实现 “多继承” 。在java中,是不存在多继承的,但是我们可以通过Runnable接口调用其他类来实现多继承的功能。
public void test_MyThread_2() {
MyThread_2 mt1 = new MyThread_2("线程A "); // 实例化对象
MyThread_2 mt2 = new MyThread_2("线程B "); // 实例化对象
Thread t1 = new Thread(mt1);// 也可以是其他的实现类,只要是实现Runnable接口的就行。相当于实现了多继承,就可以使用这个类里面的各种方法。
Thread t2 = new Thread(mt2);
t1.start(); // 调用线程主体
t2.start(); // 调用线程主体
}
-更高的资源的利用率。可以把前者比作高通骁龙,后者比作 联发科 。两者都可以同时干多个任务。但是,前者不能多个人同时干一个任务,而后者可以 ,不会让造成 一核有难,七核围观 的尴尬局面。
// 1、继承 Thread 类
class MyThread_1 extends Thread {
private int count = 10;
private String name;
public MyThread_1(String name) {
this.name = name;
}
// 覆写run()方法,作为线程 的操作主体
public void run() {
while (count>0){
System.out.println(name + "运行" + "count=" + this.count--);
}
}
}
// 测试
@Test
public void test_MyThread_1() {
MyThread_1 mt1 = new MyThread_1("线程A "); // 实例化对象
MyThread_1 mt2 = new MyThread_1("线程B "); // 实例化对象
mt1.start(); // 调用线程主体
mt2.start(); // 调用线程主体
}
// 输出结果
/*
Thread-1运行count=5
Thread-0运行count=5
Thread-1运行count=4
Thread-0运行count=4
Thread-1运行count=3
Thread-0运行count=3
Thread-1运行count=2
Thread-0运行count=2
Thread-1运行count=1
Thread-0运行count=1
*/
// 2、实现 Runnable 接口
public class MyThread implements Runnable {
private int count = 10;
// 覆写run()方法,作为线程 的操作主体
public void run() {
System.out.println("1、进入run()方法");
while (count > 0) {
System.out.println(Thread.currentThread().getName() + "运行" + "count=" + this.count--);
}
}
}
// 测试
@Test
public void test_MyThread_3() {
MyThread_2 mt = new MyThread_2("线程 "); // 实例化对象
// 同一个mt ,只有在 Runnable中可以 ,在Thread中会出现异常报错。
new Thread(mt).start();
new Thread(mt).start();
new Thread(mt).start();
}
// 执行结果
/*
1、进入run()方法
1、进入run()方法
1、进入run()方法
Thread-1运行count=8
Thread-2运行count=9
Thread-0运行count=10
Thread-2运行count=6
Thread-1运行count=7
Thread-2运行count=4
Thread-0运行count=5
Thread-2运行count=2
Thread-1运行count=3
Thread-0运行count=1
*/
4、完整代码演示
package demo;
import org.junit.jupiter.api.Test;
/**
* @author LS
* @create 2021-09-28 17:15
*/
public class MyThread extends Thread {
@Test
public void test_MyThread_1() {
MyThread_1 mt1 = new MyThread_1("线程A "); // 实例化对象
MyThread_1 mt2 = new MyThread_1("线程B "); // 实例化对象
mt1.start(); // 调用线程主体
mt2.start(); // 调用线程主体
}
@Test
public void test_MyThread_3() {
MyThread_2 mt = new MyThread_2("线程 "); // 实例化对象
// 同一个mt ,只有在 Runnable中可以 ,在Thread中会出现异常报错。
new Thread(mt).start();
new Thread(mt).start();
new Thread(mt).start();
}
}
// 1、继承 Thread 类
class MyThread_0 extends Thread {
private int count = 5;
// 覆写run()方法,作为线程 的操作主体
public void run() {
while (count > 0) {
System.out.println(Thread.currentThread().getName() + "运行" + "count=" + this.count--);
}
}
}
// 2、实现 Runnable 接口
class MyThread implements Runnable {
private int count = 10;
// 覆写run()方法,作为线程 的操作主体
public void run() {
System.out.println("1、进入run()方法");
while (count > 0) {
System.out.println(Thread.currentThread().getName() + "运行" + "count=" + this.count--);
}
}
}