Java线程的创建方式以及线程池的使用

本文详细介绍了Java中线程的多种创建方式,包括CompletableFuture的使用,展示了如何自定义线程池,讨论了线程池的执行流程、执行策略以及线程调度方法。还探讨了为什么使用线程池,以及线程池和直接调用run方法的区别。最后,文章提到了CountDownLatch的使用和线程池相关最佳实践。

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

Java线程的创建方式以及线程池的使用

一、线程的创建方式一

/**
  * 1.继承thread类,重写run方法
*/
@Test
void test1(){
   
    new threadDemo().start();
}

class threadDemo extends Thread{
   
    @Override
    public void run() {
   
        for (int i = 0; i < 10; i++) {
   
            System.out.println(i);
        }
    }
}

二、线程的创建方式二

/**
  * 2.实现runnable接口,重写run方法
*/
@Test
void test2(){
   
    new Thread(new runnableDemo()).start();
}

class runnableDemo implements Runnable{
   
    @Override
    public void run() {
   
        for (int i = 0; i < 10; i++) {
   
            System.out.println(i);
        }
    }
}

三、线程的创建方式三

/**
  * 3.实现Callable接口,重写call方法
*/
@Test
void test3(){
   
    FutureTask<Integer> futureTask = new FutureTask<>(new callAbleDemo());
    new Thread(futureTask, "threadName").start();

    Integer result = null;
    try {
   
        // 获取子线程执行的结果,此时主线程会被阻塞,会等到计算结果完成后,容易程序阻塞
        // 可以通过使用CompletableFuture,解决FutureTask的缺陷问题
        result = futureTask.get();
    } catch (InterruptedException e) {
   
        e.printStackTrace();
    } catch (ExecutionException e) {
   
        e.printStackTrace();
    }

    System.out.println(result);  // 输出result为45
}


class callAbleDemo implements Callable<Integer>{
   

    @Override
    public Integer call() throws Exception {
   
        int sum = 0;
        for (int i = 0; i < 10; i++) {
   
            sum += i;
        }
        return sum;
    }
}

由于futureTask.get()时会阻塞主线程,我们可以指定超时时间,表示在规定时间内仍未完成则直接抛异常,改造后的代码如下:

/**
  * 3.实现Callable接口,重写call方法
*/
@Test
void test3(){
   
    FutureTask<Integer> futureTask = new FutureTask<>(new callAbleDemo());
    new Thread(futureTask, "threadName").start();

    Integer result = null;
    try {
   
        // 获取子线程执行的结果,此时主线程会被阻塞,会等到计算结果完成后,容易程序阻塞
        // 可以通过使用CompletableFuture,解决FutureTask的缺陷问题
        // result = futureTask.get();
        result = futureTask.get(3, TimeUnit.SECONDS); // 指定超时时间,如果未执行完直接抛异常
    } catch (InterruptedException e) {
   
        e.printStackTrace();
    } catch (ExecutionException e) {
   
        e.printStackTrace();
    } catch (TimeoutException e) {
   
        e.printStackTrace();
    }

    System.out.println(result);
}

class callAbleDemo implements Callable<Integer>{
   

    @Override
    public Integer call() throws Exception {
   
        int sum = 0;
        for (int i = 0; i < 10; i++) {
   
            sum += i;
        }
        try {
   
            TimeUnit.SECONDS.sleep(5); // 沉睡5s,模拟耗时操作
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
        return sum;
    }
}

在这里插入图片描述

同时我们也可以使用FutureTaskisDone方法,这个方法的作用是不断地轮询判断是否操作已经完成,但是这容易耗费cpu资源,改造后的代码如下:

/**
  * 3.实现Callable接口,重写call方法
*/
@Test
void test3() throws ExecutionException, InterruptedException {
   
    FutureTask<Integer> futureTask = new FutureTask<>(new callAbleDemo());
    new Thread(futureTask, "threadName").start();

    Integer result = null;

    // isDone轮询,是否已经计算完成,容易耗费cpu资源
    while (true){
   
        if (futureTask.isDone()){
   
            // 可以通过使用CompletableFuture,解决FutureTask的缺陷问题
            result = futureTask.get();
            break;
        }else {
   
            System.out.println("还没完成呢");
        }
    }
    System.out.println(result);
}

class callAbleDemo implements Callable<Integer>{
   

    @Override
    public Integer call() throws Exception {
   
        int sum = 0;
        for (int i = 0; i < 10; i++) {
   
            sum += i;
        }
        try {
   
            TimeUnit.SECONDS.sleep(1); // 沉睡1s,模拟耗时操作
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
        return sum;
    }
}

在这里插入图片描述

我们可以通过使用CompletableFuture,解决FutureTask的缺陷问题,FutureTask类图关系如下:

在这里插入图片描述

CompletableFuture

哔哩哔哩链接:https://www.bilibili.com/video/BV1ar4y1x727?p=22&vd_source=7c5f1f4c039688f19024d50ef51aaed1

从java8开始引入CompletableFuture,是Future的功能增强版,减少阻塞和轮询,可以传入回调对象,当异步任务完成或者发生异常时,自动调用回调对象的回调方法。

public static void main(String[] args) throws ExecutionException, InterruptedException {
   

    CompletableFuture.supplyAsync(() -> {
   
        System.out.println(Thread.currentThread().getName() + "----come in");
        int result = ThreadLocalRandom.current().nextInt(10);
        try {
   
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
        System.out.println("-----1秒钟后出结果:" + result);
        return result;
    }).whenComplete((v, e) -> {
   
        if (e == null) {
   
            System.out.println("-----计算完成,更新系统UpdateValue:" + v);
        }
    }).exceptionally(e -> {
   
        e.printStackTrace();<
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值