1. 继承Thread
创建一个Thread类的子类(即线程),需要重写run方法,把要执行的内容都写入run方法里。
public class MyThread extends Thread {
@Override
public void run() {
//要执行的任务
}
}
执行时只需new对象,然后调用start方法(⚠️注意不是调用run)。
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
}
2. 实现Runnable
创建自定义类实现Runnable接口,同样重写run方法。
public class MyRunnable implements Runnable{
@Override
public void run() {
//要执行都任务
}
}
按以下步骤执行:
public static void main(String[] args) {
//1. 创建任务对象
MyRunnable r = new MyRunnable();
//2. 创建线程对象,传入任务
Thread t = new Thread(r);
//3. 执行线程
t.start();
}
3. 用接口Callable创建带返回值的线程
创建实现Callable接口,需要指定范型,就是指定返回值的类型
class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
//要执行的任务
return 100; //返回值
}
}
按以下步骤执行:
public static void main(String[] args) {
//1. 创建执行对象
MyCallable c = new MyCallable();
//2. 创建任务对象,传入执行对象,指定范型用于接收MyCallable的返回值
FutureTask<Integer> task = new FutureTask<>(c);
//3. 创建线程对象,传入任务
Thread t = new Thread(task);
//4. 开启
t.start();
}
Runnable的优势(Callable不常用)
- 适合多个线程执行相同任务的情况
- 避免继承带来的局限性(继承只能继承一个父类,实现可以实现多个接口)
- 任务和线程分离,提高代码健壮性
- 线程池只接收Runnable不接收Thread