创建线程的三种方式

使用线程的三种方式

  • 实现Runnable接口
  • 实现Callable接口
  • 继承Thread类

实现Runnable接口和Callable接口的类只能当做是一个可以在线程中执行的任务,不是真正意义上的线程,因此最后还需通过Thread类来调用。可以理解为任务是通过线程驱动并执行的

一.实现Runnable接口

java常规写法

public class MyRunnable implements Runnable {
     @Override
     public void run() {
     // ...
     }
}
public static void main(String[] args) {
     MyRunnable instance = new MyRunnable();
     Thread thread = new Thread(instance);
     thread.start();
}

java8 Lambda表达式

public static void main(String[] args) {
   	 Runnable able = () -> {
         //任务执行体
     }
     Thread thread = new Thread(able);
     thread.start();
}

二.实现 Callable 接⼝

与 Runnable 相⽐,Callable 可以有返回值,返回值通过 FutureTask 进⾏封装。也可抛出异常放到上一级进行处理,但Runnable不能抛出,只能在方法内自行处理,且执行任务的线程不会停止。Callable会随着执行的结束而停止

public class MyCallable implements Callable<Integer> {
     public Integer call() throws Exception {
        try {
            throw new Exception();
        } catch (Exception e) {
            return 222;
        } finally {
            return 123;
        }
    }
}
public static void main(String[] args) throws ExecutionException,
InterruptedException {
 	MyCallable mc = new MyCallable();
 	FutureTask<Integer> ft = new FutureTask<>(mc);
 	Thread thread = new Thread(ft);
 	thread.start();
 	System.out.println(ft.get());		//返回123
    //Lambda表达式写法
    FutureTask<Integer> ft2 = new FutureTask<>(() -> {
        try {
            throw new Exception();
        } catch (Exception e) {
            return 222;
        } finally {
            return 123;
        }
    });
    thread = new Thread(ft2);
 	thread.start();
 	System.out.println(ft.get());		//返回123
}

其中的FutureTask类实现了RunnableFuture接口(继承了Runnable和Future接口),所以它具有获取Callable返回值且调用Runnable的同时让其返回值(其中的构造函数传入Runnable,和result两个参数,在其中用适配器模式使用Callable调用Runnable的方法,返回result)。无论两种构造方法都会构造出一个带有Callable对象的FutureTask对象,所以当线程调用start方法时会触发其中的run方法,调用其中Callable任务的call方法。

三.继承 Thread

同样也是需要实现 run() ⽅法,因为 Thread 类也实现了 Runable 接⼝。

当调⽤ start() ⽅法启动⼀个线程时,虚拟机会将该线程放⼊就绪队列中等待被调度,当⼀个线程被调度

时会执⾏该线程的 run() ⽅法。

public class MyThread extends Thread {
     public void run() {
     // ...
     }
}
public static void main(String[] args) {
     MyThread mt = new MyThread();
     mt.start();
}

实现接⼝ VS 继承 Thread

  • Java 不⽀持多重继承,因此继承了 Thread 类就⽆法继承其它类,但是可以实现多个接⼝
  • 类可能只要求可执⾏就⾏,继承整个 Thread 类开销过⼤。
posted @ 2020-12-17 09:24  whhhd  阅读(119)  评论(0编辑  收藏  举报