Javaz 创建线程主要有三种方式:继承 Thread 类创建线程、实现 Runnable 接口创建线程和实现 Callable 和 Future 创建线程。

# 继承 Thread 类

public class Thread1 extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName() + ": " + i);
        }
    }
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
            if (i == 2) {
                new Thread1().start();
                new Thread1().start();
            }
        }
    }
}

# 实现 Runnable 接口

public class Thread2 implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
        }
    }
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
            if (i == 2) {
                Thread2 thread2 = new Thread2();
                new Thread(thread2).start();
                new Thread(thread2).start();
            }
        }
    }
}

# 实现 Callable 接口

FutureTask 类包装 Callable 对象时,封装了 Callable 对象的 call () 方法的返回值。

class Thread3 implements Callable {
    @Override
    public Integer call() throws Exception {
        int i = 0;
        for (; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
        }
        return i;
    }
    public static void main(String[] args) {
        Thread3 thread3 = new Thread3();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(thread3);
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + " :" + i);
            if (i == 2) {
                new Thread(futureTask, "有返回值的线程").start();
            }
        }
        try {
            System.out.println("子线程返回值: " + futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

# 三种方式优缺点

采用实现接口(Runnable 和 Callable)的方式,线程类还可以继承其他的类。实现接口的线程对象还可以用来创建多个线程,可以实现资源共享。缺点是不能使用 this 指针来获取线程的名字等。
采用继承 Thread 类的方式,线程不能继承其他的类,但是 Thread 类中有 getName 方法,因为可以直接使用 this.getName () 来获取当前线程的名字。