学习总结:
链接:【Java基础、springboot、springcloud、docker 等,学习目录】
线程、进程相关基础概念参看【上一章:Java基础>20 - 线程基础概念】
方式一、继承Thread类:
1、继承Thread类。
2、重写Thread类的run方法。
3、创建Thread类的子类对象,调用start方法开启线程。一个线程一旦开启,那么线程就会执行run方法中的代码。run方法不能直接调用,直接调用相当于调用了一个普通方法而已,没有开启新的线程。
/**
* 自定义线程
*/
public class CustomThread extends Thread {
// 线程名称
private String name;
public CustomThread(String name) {
this.name = name;
}
// 重写 run 方法, 线程要操作的主体
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
System.out.println(name + " : " + i);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// 测试类
public class Test {
public static void main(String[] args) {
new CustomThread("线程 A").start();
new CustomThread("线程 B").start();
}
}
结果:交替打印 无规律
Thread 类常用方法:
Thread(String name):初始化线程名字。
setName(String name):设置线程对象名。
getName():返回对象名字。
sleep(long millis):休眠时间,毫秒数。
currentThread():返回当前线程对象。
setPriority():设置优先级,最小1,最大10,默认5。优先级大的只是实现的概率大。
getPriority():返回当前线程的优先级。
// 获取线程名的通用方式:
String name = Thread.currentThread().getName();
方式二、实现Runnable接口:
1、自定义一个类,实现Runnable接口。
2、实现接口的run方法,将自定义线程的任务定义在run方法中。
3、创建Runnable接口实现类对象。
4、创建Thread类对象,并把Runnable接口实现类对象作为参数传递给Thread。
5、调用Thread类对象的start方法开启一个线程。
/**
* 实现 Runnable 接口
*/
public class CustomRunnable implements Runnable {
// 线程名称
private String name;
public CustomRunnable(String name) {
this.name = name;
}
// 实现 run 方法
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
// Thread.sleep(10);
System.out.println(name + " : " + i);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// 测试:
public class Test {
public static void main(String[] args) {
CustomRunnable crA = new CustomRunnable("线程 A");
CustomRunnable crB = new CustomRunnable("线程 B");
new Thread(crA).start();
new Thread(crB).start();
}
}
// 结果:交替打印 无规律
注意:
- Runnable实现类对象并不是一个线程对象,只不过是实现了Runnable接口而已,只有Thread或Thread的子类对象才是线程对象。
- 将Runnable接口实现类对象作为实参传递给Thread对象的作用:将run方法中的任务传递给Thread去执行。
三、两种方式比较:
1、继承Thread类:
好处:代码相对较简单,可以直接使用Thread类中的方法。
弊端:耦合性强,有单继承的局限性。
2、实现Runnable接口:
好处:解耦,多继承
弊端:代码相对较复杂。Runnable接口中没有开启线程的方法,需要借助Thread类中开启线程的方法start。
3、 Thread 类也是 Runnable 接口的子类
// 部分代码
public
class Thread implements Runnable {
private Runnable target;
@Override
public void run() {
if (target != null) {
target.run();
}
}
}
匿名内部类方式:
// Thread类重写run方法
new Thread(){
@Override
public void run() {
}
}.start();
// Runnable接口实现类作为参数传递给Thread:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Runnable接口run方法:");
}
}).start();