Java 中有三种线程创建方式:

    • 实现 Runnable 接口的 run 方法
    • 继承 Thread 类并重写 run 的方法
    • 实现 Callable接口,使用 FutureTask 方式。

    首先看继承 Thread 类方式的实现。

    1. public class ThreadTest {
    2. //继承 Thread 类并重写 run 方法
    3. public static class MyThread extends Thread {
    4. @Override
    5. public void run() {
    6. System.out.println(「I am a child thread」);
    7. }
    8. }
    9. public static void mainString[] args {
    10. // 创建线程
    11. MyThread thread = new MyThread();
    12. // 启动线程
    13. thread.start();
    14. }
    15. }

    使用继承方式的好处是,在 run()方法内获取当前线程直接使用 this 就可以了,无须使用 Thread.currentThread()方法;而如果使用 Runnable 方式,则只能使用主线程里面被声明为 final 的变量。

    不好的地方是 Java 不支持多继承,如果继承了 Thread 类,那么就不能再继承其他类。另外任务与代码没有分离,当多个线程执行一样的任务时需要多份任务代码,而 Runable 则没有这个限制。

    下面看实现 Runnable 接口的 run 方法方式。

    1. public static class RunableTask implements Runnable{
    2. @Override
    3. public void run() {
    4. System.out.println("I am a child thread");
    5. }
    6. }
    7. public static void main(String[] args) throws InterruptedException{
    8. RunableTask task = new RunableTask();
    9. new Thread(task).start();
    10. new Thread(task).start();
    11. }

    但是上面介绍的两种方式都有一个缺点,就是任务没有返回值。下面看最后一种,即使用 FutureTask 的方式。

    //创建任务类,类似 Runable
    public static class CallerTask implements Callable<String>{
            @Override
            public String call() throws Exception {
                return 「hello」;
            }
        }
        public static void main(String[] args) throws InterruptedException {
        // 创建异步任务 
            FutureTask<String> futureTask  = new FutureTask<>(new CallerTask());
            //启动线程 
            new Thread(futureTask).start();
            try {
              //等待任务执行完毕,并返回结果 
                String result = futureTask.get();
                System.out.println(result);
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
    }