java实现多线程的方式(三种)

本文详细介绍了在Java中实现多线程的三种主要方法:继承Thread类并重写run方法,实现Runnable接口并重写run方法,以及实现Callable接口并重写call方法。通过具体的代码示例,深入解析了每种方法的实现细节和注意事项。

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

最近在学习java多线程,在这里记录一下实现多线程的方式:

1.继承Tread类,重写run方法:

public class TheadTest01 {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            // 使用start方法开启线程
            new MyThread(i).start();
        }
    }
}

// 继承Thread类
class MyThread extends Thread {
    private int i;

    public MyThread(int i) {
        this.i = i;
    }

    // 重写run方法
    @Override
    public void run() {
        System.out.print(i + " ");
    }
}

2.实现Runnable接口,重写run方法:

public class RunnableTest01 {

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            Runnable ra = new MyRunnable(i);
            // 通过Thread的构造函数传入参数,使用start方法开启线程
            new Thread(ra).start();
        }
    }

}

// 实现Runnable接口
class MyRunnable implements Runnable {

    private int i;

    public MyRunnable(int i) {
        this.i = i;
    }
	
	// 实现run方法
    @Override
    public void run() {
        System.out.println(i);
    }

}

这里需要将Runnable对象当做参数通过构造函数传入创建的Thread对象中,这里简单看一下Thread类的源码:

public class Thread implements Runnable

首先可以看到Thread类也实现了Runnable接口,再看一下Thread的run方法:

	@Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

可以发现,Thread类的run方法只是运行传入Runnable对象的run方法,自身没有做过多实现。

3.实现Callable接口,重写call方法:

public class CallableTest01 {
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 10; i++) {
            // 创建Callable对象
            Callable<Integer> ca = new MyCallable(i);
            // 创建FutureTask对象,并通过构造函数将Callable对象传入
            FutureTask<Integer> future = new FutureTask<Integer>(ca);
            // 创建Thread对象,将FutureTask对象当做参数传入,通过start方法启动线程
            // Runnable ra = future;
            // new Thread(ra).start();
            new Thread(future).start();
        }
    }
}

// 实现Callable接口
class MyCallable implements Callable<Integer> {
    private int i;

    public MyCallable(int i) {
        this.i = i;
    }

    // 重写call方法
    @Override
    public Integer call() throws Exception {
        System.out.println(i);
        return i;
    }
}

可以发现,使用Callable接口实现多线程,需要将Callable对象通过构造函数传入创建的FutureTask对象中,然后将FutureTask对象通过构造函数传入Thread对象中,才能运行。通过观察Thread的构造函数发现并不能接受FutureTask类型的参数,为什么还能传入呢?这是因为FutureTask类实现了Runnable接口:

public class FutureTask<V> implements RunnableFuture<V>

public interface RunnableFuture<V> extends Runnable, Future<V>

所以Thread类可以接受FutureTask作为构造参数,类似于:

Runnable ra = future;
new Thread(ra).start();

使用Callable接口实现多线程还是可以获取返回值的,使用FutureTask对象的get方法即可,不过如果对每个FutureTask对象直接使用get方法的话,会因为阻塞而不能实现多线程的效果,这时可以通过集合搜集FutureTask对象,然后调用get方法,代码如下:

public static void main(String[] args) throws Exception {
        // 创建FutureTask<Integer>集合
        List<FutureTask<Integer>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            // 创建Callable对象
            Callable<Integer> ca = new MyCallable(i);
            // 创建FutureTask对象,并通过构造函数将Callable对象传入
            FutureTask<Integer> future = new FutureTask<Integer>(ca);
            // 将FutureTask对象放入集合中
            list.add(future);
            // 创建Thread对象,将FutureTask对象当做参数传入,通过start方法启动线程
            new Thread(future).start();
            // 不能实现异步
            // System.out.println(future.get());
        }

        // 使用FutureTask对象的get方法获取返回值
        int result = 0;
        for (int i = 0, len = list.size(); i < len; i++) {
            result += list.get(i).get();
        }
        System.out.println("\nresult=" + result);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coder-文小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值