Skip to content

创建线程方式

继承 Thread 类

java
public class ThreadExtendTest {


    public static class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println("I'm child thread name is" + this.getName());
        }
    }

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
    }
}
  • MyThread 类继承 Thread 类, 重写了 run()方法。main 函数创建 MyThread 实例,调用改实例的 start 方法启动线程。
  • 当创建完 thread 对象后该线程并没有被启动执行,直到调用了 start 方法后才真正启动了线程。其实调用 start 方法后线程并没有马上执行而是处于就绪状态, 这个就绪状态是指该线程已经获取了除 CPU 资源外的其他资源,等待获取 CPU 资源后才会真正处于运行状态
  • 一旦 run 方法执行完毕,该线程就处于终止状态
  • 在 run() 方法内获取当前线程直接使用 this 就可以了,无须使用 Thread. currentThread() 方法;
  • 不好的地方是 Java 不支持多继承,如果继承了 Thread 类,那么就不能再继承其他类。另外任务与代码没有分离, 当多个线程执行一样的任务时需要多份任务代码,而 Runable 则没有这个限制。

实现 Runnable 接口

java
public class ThreadImplRunnableTest {

    public static class RunnableImpl implements Runnable {

        @Override
        public void run() {
            System.out.println("RunnableImpl.run on " + Thread.currentThread().getName());
        }
    }

    public static void main(String[] args) {
        RunnableImpl runnableImpl = new RunnableImpl();
        Thread thread = new Thread(runnableImpl);
        thread.start();

        Thread thread1 = new Thread(runnableImpl);
        thread1.start();
    }
}
  • 两个线程共用一个 task 代码逻辑,如果需要,可以给 RunableTask 添加参数进行任务区分。另外, RunableTask 可以继承其他类。但是上面介绍的两种方式都有一个缺点,就是任务没有返回值

FutureTsk

java
public class CallableTaskTest {

    public static class CallableTask implements Callable<String> {

        @Override
        public String call() throws Exception {
            return " executor task job";
        }
    }


    public static void main(String[] args) throws Exception {
        FutureTask task = new FutureTask<>(new CallableTask());
        new Thread(task).start();
        String result = (String) task.get();
        System.out.println(result);
    }
}
  • CallerTask 类实现了 Callable 接口的 call()方法。在 main 函数内首先创建了一个 FutrueTask 对象(构造函数为 CallerTask 的实例),然后使用创建的 FutrueTask 对象作为任务创建了一个线程并且启动它,最后通过 futureTask.get() 等待任务执行完毕并返回结果。

使用线程池方式

java
public class ThreadPoolThreadTest {

    public static void main(String[] args) {
            ExecutorService executor = Executors.newFixedThreadPool(5);//创建一个固定大小的线程池
            for (int i = 0; i < 10; i++) {
                int taskId = i;
                executor.execute(()->{
                    System.out.println("Executing task "+ taskId);
                });
            }
            executor.shutdown();//关闭线程池
    }
}

Released under the MIT License.