介绍
Oracle上说创建线程分为两类,准确地讲,创建线程只有一种方式,就是通过构造Thread类,而实现线程的执行单元有两种方法
-
方法1:实现Runnable接口的run()方法,并把Runnable实例传给Thread类。
-
方法2 : 重写Thread的run()方法,即继承Thread类。
实现Runable接口的run()方法
实现步骤:
- 重写run()方法;
- Thread传进实现类,调用start()方法启动线程。
public class CreateThreadDemo2 implements Runnable {
// 实现Runnable接口的run()方法
@Override
public void run() {
System.out.println("线程创建方法2 : 实现Runnable接口的run()方法");
}
public static void main(String[] args) {
CreateThreadDemo2 c2 = new CreateThreadDemo2();
// 传进实现类,启动线程
new Thread(c2).start();
}
}
继承Thread类
实现步骤:
- 重写run()方法;
- 调用start()方法启动线程。
public class CreateThreadDemo1 extends Thread {
// 重写run()方法
@Override
public void run() {
System.out.println("线程创建方法1 : 继承Thread");
}
public static void main(String[] args) {
CreateThreadDemo1 c1 = new CreateThreadDemo1();
// 启动线程
c1.start();
}
}
其他方法
实现Callable接口的call()方法
实现步骤:
- 重写call()方法;
- 创建FutureTask实现类。
- Thread类传入FutureTask实现类。
public class CreateThreadDemo3 implements Callable {
@Override
public String call() throws Exception {
// 模拟耗时任务
Thread.sleep(3000);
System.out.println("MyCallable 线程:" + Thread.currentThread().getName());
return "MyCallable";
}
public static void main(String[] args) {
// Callable接口的实现类
CreateThreadDemo3 c3 = new CreateThreadDemo3();
// FutureTask实现了runnable接口
FutureTask<String> task=new FutureTask<>(c3);
Thread t=new Thread(task);
t.start();
}
}
Callable 与 Runnable的区别与联系:
区别:
- Callable 可以在任务结束的时候提供一个返回值,Runnable 无法提供这个功能
- Callable 的 call 方法分可以抛出异常,而 Runnable 的 run 方法不能抛出异常。
联系:
- 在Tread中有一个构造方法是传入一个Runnable接口类型的参数,而上面的FutureTask实例实现了 RunnableFuture 接口,RunnableFuture 接口又继承了Runnable接口和 Funture接口,因此我们可以将FutureTask 的一个实例当做是一个Runnable接口的实例传入Thread来启动我们新建的线程。
public class FutureTask<V> implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V>
通过线程池创建线程
链接: https://blog.youkuaiyun.com/slj821/article/details/106769191.
总结
无论我们以怎样的形式实现多线程,都需要调用Thread类中的start方法去向操作系统请求io,cup等资源。