异步和线程池

一、基础知识

1、初始化线程的4种方式

1.1继承Thread类

 public static class Thread01 extends Thread  {
        @Override
        public void run() {
            System.out.println("当前线程:" + Thread.currentThread().getId());
            int i = 10/2;
            System.out.println("运行结果: " + i);
        }
 }

//调用
Thread01 thread01 = new Thread01();
thread01.start();

1.2实现Runnable接口

public static class Runnable01 implements Runnable {

        @Override
        public void run() {
            System.out.println("当前线程:" + Thread.currentThread().getId());
            int i = 10/2;
            System.out.println("运行结果: " + i);
        }
 }

Runnable01 runnable01 = new Runnable01();
new Thread(runnable01).start();

1.3实现Callable接口+FutureTask(可以拿到返回结果,可以处理异常)

public static class Callable01 implements Callable<Integer> {

        @Override
        public Integer call() throws Exception {

            System.out.println("当前线程:" + Thread.currentThread().getId());
            int i = 10/2;
            System.out.println("运行结果: " + i);
            return i;

        }
    }


//3)、实现 Callable 接口 + FutureTask (可以拿到返回结果,可以处理异常)
FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
new Thread(futureTask).start();

Integer integer = futureTask.get(); 
//等待整个线程执行完成,拿到返回结果 阻塞等待

1.4线程池

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,
                200,
                10,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(200),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());



/**
         * newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
         * newFixedThreadPool  创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
         * newScheduledThreadPool  创建一个定长线程池,支持定时及周期性任务执行。
         * newSingleThreadExecutor  创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务
         *                          按照指定顺序(FIFO, LIFO, 优先级)执行。
         */

七大参数
1、corePoolSize:核心线程数;线程池创建号后就准备就绪的线程数量【一直存在,除非 allowCoreThreadTimeOut 设置了】,就等待接受异步任务执行。
2、maximumPoolSize 最大线程数; 控制资源,
3、keepAliveTime  存活时间 。 如果当前正在运行的线程数量大于core , 释放空闲的线程【超过核心数的那一部分】,线程空闲大于指定的存活时间keepAliveTime。
4、unit 时间单位
5、workQueue   阻塞队列,如果任务有很多,就会将目前多的任务放在队列里面,只要有线程空闲了,就会去队列里面取新的任务执行 new LinkedBlockingDeque<>() 默认是 Integer的最大值。 太大了要自己指定
6、threadFactory   线程创建的工厂
7、handle   如果队列满了,应该怎么操作。  拒绝策略

流程
     (1) 、core 满了,就将再进来的任务放入阻塞队列中。空闲的 core 就会自己去阻塞队
     列获取任务执行
     (2) 、阻塞队列满了,就直接开新线程执行,最大只能开到 max 指定的数量
     (3) 、max 都执行好了。Max-core 数量空闲的线程会在 keepAliveTime 指定的时间后自
     动销毁。最终保持到 core 大小
     (4) 、如果线程数开到了 max 的数量,还有新任务进来,就会使用 reject 指定的拒绝策
     略进行处理



一个线程池 core 7  max 20  queue 50    100并发进来怎么分配
7 个立即执行  50个进入队列  再开13个执行  30被拒绝

 总结

1、2不能得到返回值,3可以获得返回值

1、2、3不能控制资源,4可以控制资源的使用

二、CompletableFuture异步编排

CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果: " + i);
        }, executorService);

        //方法完成后的感知
        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getId());
            int i = 10 / 0;
            System.out.println("运行结果: " + i);
            return i;
        }, executorService).whenComplete((res, ex) -> { //得到异常信息,但是没法修改结果
            System.out.println("异步任务完成了......结果是:" + res + ";异常是:" + ex);
        }).exceptionally(throwable -> {
            return 10;//出现异常后,可以指定默认返回
        });

        //方法执行完成后的处理
        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果: " + i);
            return i;
        }, executorService).handle((res, ex)->{
            if (res != null) {
                return res * 2;
            }
            if (ex != null) {
                return 0;
            }
            return 0;
        });



/**
         * 两个任务只要有一个完成,就执行任务3
         * runAfterEitherAsync 不感知结果,也没有返回值
         */
        future1.runAfterEitherAsync(future2, () -> {
            System.out.println("任务3开始");
        }, executorService);


//两个任务都完成才执行任务3
        future1.runAfterBothAsync(future2, () -> {
            System.out.println("任务3开始");
        } ,executorService);

相关推荐

  1. 异步线

    2024-07-14 18:06:03       24 阅读
  2. C++同异步极致线

    2024-07-14 18:06:03       64 阅读
  3. SpringBoot 线异步调用

    2024-07-14 18:06:03       42 阅读
  4. 线,我的异常呢?

    2024-07-14 18:06:03       43 阅读
  5. Spring Boot中异步线@Async

    2024-07-14 18:06:03       43 阅读
  6. c++ 实现线、实现异步接口

    2024-07-14 18:06:03       32 阅读
  7. C++11 Thead线线

    2024-07-14 18:06:03       41 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-14 18:06:03       101 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-14 18:06:03       109 阅读
  3. 在Django里面运行非项目文件

    2024-07-14 18:06:03       87 阅读
  4. Python语言-面向对象

    2024-07-14 18:06:03       96 阅读

热门阅读

  1. Go:常量&运算符&流程控制

    2024-07-14 18:06:03       20 阅读
  2. qiankun子应用vue加载js资源失效问题解决

    2024-07-14 18:06:03       23 阅读
  3. 深入理解C++11中的std::packaged_task

    2024-07-14 18:06:03       26 阅读
  4. 华为 NAT 技术介绍及配置

    2024-07-14 18:06:03       23 阅读
  5. prompt第三讲-PromptTemplate

    2024-07-14 18:06:03       22 阅读
  6. 微信小程序的目录结构

    2024-07-14 18:06:03       31 阅读