创建线程的四种方式

本文介绍了Java创建线程的四种方式,包括继承Thread类、实现Runnable接口、实现Callable接口和使用线程池。阐述了每种方式的优缺点,如继承Thread类不支持多继承且无返回值,实现Callable接口可获取异步结果等,还提及了手写创建线程的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建线程的四种方式和区别

1. 继承 Thread 类并重写run方法
  • 缺点:Java不支持多继承,继承Thread类后就不能继承其他类了;多个线程之间不能共享线程类的实例变量。没有返回值。
2. 实现 Runnable 接口
  • 优点:还可以继承其他类; 多个线程共享同一个target对象,所以适合多个相同线程来处理同一个份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,体现了面向对象的思想。
  • 缺点:没有返回值。
3. 实现 Callable 接口
  • 优点:还可以继承其他类; 多个线程共享同一个target对象,所以适合多个相同线程来处理同一个份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,体现了面向对象的思想; FutureTask 配合可以用来获取异步执行的结果。
  • 返回的是一个 Future,通过它的 isDone 方法可以判断任务是否完成,如果任务已完成,那么可以通过它的get方法获取返回结果。也可以使用 FutureTask,因为Future是一个接口,无法直接用来创建对象进行使用,而FutureTask是一个实现类,它实现了 RunnableFuture 接口,这个接口继承了Runnable接口和Future接口,所以它既可以作为Runnable被线程执行,也可以作为Future得到Callable的返回值。
    Callable和Runnable的区别:Runnable接口不会返回结果和抛出异常,Callable接口可以返回结果和抛出异常。
import java.util.concurrent.*;

public class fz {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        Task task = new Task();

//        Future<Integer> res1 = executor.submit(task);
//        executor.shutdown();

        FutureTask<Integer> res2 = new FutureTask<>(task);
        executor.submit(res2);
        executor.shutdown();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        System.out.println("主线程在执行任务");

        try {
            System.out.println("task运行结果" + res2.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        System.out.println("所有任务执行完毕");
    }
}

class Task implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        System.out.println("子线程在进行计算");
        Thread.sleep(3000);
        int sum = 0;
        for (int i = 0; i < 100; i++)
            sum += i;
        return sum;
    }
}

4. 线程池的方式:Java中提供了一个Executors的类,通过它可以直接帮我们创建常用的线程池,比如:

Executors.newSingleThreadExecutor()
Executors.newFixedThreadPool()
Executors.newCachedThreadPool()
Executors.newScheduledThreadPool()
  

5. 手写创建线程的四种方式

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.*; //现场手写可以只写这一个

public class MyThread {
    //方法一:继承 Thread
    public static class MyThread1 extends Thread {

        @Override
        public void run() {
            //...
        }
    }

    //方法二:实现 Runnable
    public static class MyThread2 implements Runnable {

        @Override
        public void run() {
            //...
        }
    }

    //方法三:实现 Callable
    public static class MyThread3 implements Callable<Integer> {

        @Override
        public Integer call() throws Exception {
            return 123;
        }
    }

    public static void main(String[] args) {
        MyThread1 m1 = new MyThread1();
        m1.start();

        MyThread2 m2 = new MyThread2();
        Thread t2 = new Thread(m2);
        t2.start();

        MyThread3 m3 = new MyThread3();
        FutureTask<Integer> ft = new FutureTask<>(m3);
        Thread t3 = new Thread(ft);
        t3.start();

        //方法四:线程池
        ExecutorService e = Executors.newCachedThreadPool();
        //lambda表达式
        e.execute(() -> {
            //...
        });
        e.shutdown();

        e.execute(new Runnable() {
            @Override
            public void run() {
                //...
            }
        });
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值