JAVA多线程基础篇 2、如何创建线程

本文详细介绍了Java中创建线程的六种方法,包括继承Thread类、实现Runnable接口、利用lambda简化、实现Callable接口获取返回值以及使用线程池。通过实例代码展示了每种方法的使用,并强调了线程池的重要性。最后,文章提供了开源项目链接以供进一步学习。

孔乙己蘸着酒,在桌上了写下五种创建线程的方法。

1. 继承自Thread类

  • 不足:java只允许单继承,一旦继承了Thread类就无法再继承其他类了。
public class ExThreads extends Thread {
    @Override
    public void run() {
        System.out.println("我是t1线程");
    }

    public static void main(String[] args) {
        Thread t1 = new ExThreads();
        t1.start();
    }
}

2. 实现Runnable接口

Thread类的构造方法允许传入一个对象,该对象必须实现Runnable接口。
这其实是一个典型的设计模式:静态代理。Thread类在执行的时候,实际上调用的就是这个对象的run方法。
这让我想起一部电影《师父》,咏春拳要在天津开武馆,需要收一个天津本地人为弟子,让他代替师父去踢馆。

public class ImpRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("我是t1线程");
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(new ImpRunnable());
        t1.start();
    }
}

3. 实现Runnable接口(二)

借助于lambda表达式,简化。

public class ImpRunnable2 {

    public static void main(String[] args) {
        Thread t1 = new Thread(()->{
            System.out.println("我是t1线程");
        });
        t1.start();
    }
}

4. 实现Callable接口

由于java线程运行是void类型,没有返回值。后来增加了Callable接口,可以返回一个泛型返回值。

public class FutureCallableThread implements Callable<String> {

    @Override
    public String call() throws Exception {
        return LocalDateTime.now().toString();
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Future<String> future = executorService.submit(new FutureCallableThread());
        //此时使用线程池提交任务后,future.get()方法是阻塞的,会等待call()完成返回。
        String str = future.get();
        System.out.println(str);
        executorService.shutdown();
    }
}

5. 实现Callable接口(二)

FutureTask实现了Runnable接口,因此用他能构建线程类。同时,他也继承了Future接口,可以返回future。

public class FutureTaskThread implements Callable<String> {

    @Override
    public String call() throws Exception {
        return LocalDateTime.now().toString();
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //先包住一层
        FutureTask<String> task = new FutureTask(new FutureCallableThread());
        //再包住一层
        Thread t1 = new Thread(task);
        t1.start();
        System.out.println(task.get());
    }
}

6. 借助于线程池

其本质还是和前面几种是一样的。

public class UsingExecutors {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是t1线程");
            }
        });
        executorService.shutdown();
    }
}

总结

线程创建方式很多,其核心还是Runnable接口和Thread类。

多线程系列在github上有一个开源项目,主要是本系列博客的实验代码。

https://github.com/forestnlp/concurrentlab

如果您对软件开发、机器学习、深度学习有兴趣请关注本博客,将持续推出Java、软件架构、深度学习相关专栏。

您的支持是对我最大的鼓励。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

悟空学编程

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

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

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

打赏作者

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

抵扣说明:

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

余额充值