java创建线程的方式

继承创建

通过继承Thread来创建线程,由于java的单继承性,对子类的限制比较多,子类结构也会比较单一,大多是业务场景并不适用这个方案。

/**
 * @Project: MySpringBoot
 * @Package: com.example.demo.common.utils.async
 * @ClassName: MyThread
 * @Description: TODO
 * @Author: xueyujiao
 * @Date: 2024/3/7
 * @Version 1.0
 */
public class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("重写父类的run方法!");
    }
}

// 调用
	MyThread myThread = new MyThread();
	myThread.start();

实现接口创建

java不支持多继承,但支持多实现接口,runnable和callable提供了这种方法进行创建线程。

Runnable

/**
 * @Project: MySpringBoot
 * @Package: com.example.demo.common.utils.async
 * @ClassName: MyRunnable
 * @Description: TODO
 * @Author: xueyujiao
 * @Date: 2024/3/7
 * @Version 1.0
 */
public class MyRunnable implements Runnable {

    private String name;

    public MyRunnable(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println( name + "runnable 执行!");
    }
}

Callable

callable与runnable的不同是,callable可以自定义返回值。

/**
 * @Project: MySpringBoot
 * @Package: com.example.demo.common.utils.async
 * @ClassName: MyCallable
 * @Description: TODO
 * @Author: xueyujiao
 * @Date: 2024/3/7
 * @Version 1.0
 */
public class MyCallable implements Callable<Map> {

    private String name;

    public MyCallable(String name) {
        this.name = name;
    }

    @Override
    public Map<String, String> call() throws Exception {
        Map<String, String> map = new HashMap<>();
        map.put("result", "call end!" + name);
        return map;
    }
}

线程池创建

以上三种是普遍使用的三种创建线程的方式,还有一种是通过线程池来实现

 ExecutorService executorService = Executors.newFixedThreadPool(10);
 // 无返回值
 executorService.execute(new MyRunnable("线程池A-1"));
 // 有返回值
 Future<Map> submit = executorService.submit(new MyCallable("线程池A-1"));
 Map<String, String> map = submit.get();
 System.out.println(map);

其他方式

以上几种,底层都是基于runnable来实现的。其实还可以简化为lambda表达式:

        // 创建匿名类
        new Thread() {
            @Override
            public void run() {
                System.out.println("继承Thread!");
            }
        }.start();

        // blambda表达式
        new Thread(() -> {
            // 实现Runnable接口
        }).start();

        // 实现callable
        FutureTask<String> futureTask1 = new FutureTask<String>(() ->{
            return "futureTask1线程";
        });

总结

在正常项目开发中,最好不要直接使用Exexutors来创建线程池,可以使用FixedThreadPool来自定义线程池。首先看一下Executors.newFixedThreadPool是如何构建线程池
在这里插入图片描述
若设置当前线程池固定大小为10,核心线程和最大线程为10,阻塞队列使用LinkedBlockingQueue(无界阻塞队列),之所以被称为无界队列,是由于该链表最大值为Integer.MAX_VALUE(2147483647),当线程特别多时,会不断增加到链表中,占用过多内存,最终导致OOM。

建议自定义new ThreadPoolExecutor(),传入适应项目运行的参数
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值