异步-线程池

https://www.cnblogs.com/frankyou/p/10135212.html

package com.kaki.gulimall.search.thread;

import java.util.concurrent.*;

// 多线程测试不能使用 @Test 测试类 测不出效果
public class Threadtest {

    /**    异步 线程池    这些感觉都是异步线程 先打印了main start main end 线程还没执行完 执行完了才
     * 打印线程中的方法
     *    初始化线程的四种方式
     *    1)、继承 Thread
     *    2)、实现 Runnable 接口
     *    3)、实现 Callable 接口 + FutureTask (可以拿到返回结果,可以处理异常)
     *    4)、线程池
     */

    public static ExecutorService executorService = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main ....start....");
        //1.继承 Thread
//        Thread01 thread01 = new Thread01();
//        thread01.start();

        //2.实现 Runnable 接口
//        Runnable01 runnable01 = new Runnable01();
//        new Thread(runnable01).start();
        //3. 实现 Callable 接口 + FutureTask (可以拿到返回结果,可以处理异常)
        /**
         *  点进 FutureTask 可以看到他接收一个  Callable01
         *  而FutureTask 又实现了RunnableFuture    RunnableFuture 又继承了 Runnable
         *  由第二个可知 new Thread可以接收一个 Runnable
         */
//        FutureTask<Integer> integerFutureTask = new FutureTask<>(new Callable01());
//        new Thread(integerFutureTask).start();
//        //阻塞等待线程执行完 一直要等到前面的所有异步方法执行完 获取返回结果
//        Integer ires = integerFutureTask.get();
//        //这个时候这一句就会在最后打印  因为他要等线程执行完获取到ires才打印
//        System.out.println("main.....end....."+ires);


        //一个系统一两个线程池?
        //executorService.submit()
        //executorService.execute(new Runnable01());
        //阿里建议使用原生的方法创建线程池  不用 Executors.newFixedThreadPool(10);
        /**
         *   创建线程池的七大参数:
         *   1.corePoolSize 核心线程数 一直保持准备就绪存活的线程数量
         *                  除非设置了allowCoreThreadTimeOut 那这个线程空闲了就会被回收关闭
         *   2. maximumPoolSize 允许的最大线程数   控制资源
         *   3. keepAliveTime 非核心线程 能够空闲的时间 (maximumPoolSize - corePoolSize)
         *                    超过这个时间还没有接收新任务 就释放(回收?关闭?)这个空闲线程
         *                    解雇临时工
         *   4. unit 时间单位
         *   5.  BlockingQueue<Runnable> workQueue  任务的阻塞队列  如果任务有很多 线程不够了
         *                                         就会将多余的任务放在队里里
         *                                         只要有空闲线程 就会到队列里去取任务来执行
         *   6.  ThreadFactory threadFactory 线程的创建工厂
         *   7.  RejectedExecutionHandler handler  如果队列满了  按照我们指定的策略拒绝执行任务
         *
         *
         *
         *   运行流程:
         *   1、线程池创建,准备好 core 数量的核心线程,准备接受任务
         *   2、新的任务进来,用 core 准备好的空闲线程执行。
         *       (1) 、core 满了,就将再进来的任务放入阻塞队列中。
         *       空闲的 core 就会自己去阻塞队 列获取任务执行
         *       (2) 、阻塞队列满了,就直接开新线程执行,最大只能开到 max 指定的数量
         *       (3) 、max 都执行好了。Max-core 数量空闲的线程会在 keepAliveTime
         *       指定的时间后自 动销毁。最终保持到 core 大小
         *       (4) 、如果线程数开到了 max 的数量,还有新任务进来,
         *       就会使用 reject 指定的拒绝策 略进行处理
         *   3、所有的线程创建都是由指定的 factory 创建的。
         *
         *     任务的阻塞队列 点进去  ctrl+h 可以看到很多实现类
         *     LinkedBlockingQueue<>()  默认这个队列的大小是  Integer的最大值  就是说可以放Integer的最大值那么多个任务
         *     内存会不够的  需要自己指定
         *
         *    194集 17分钟 老师大概讲了几种拒绝策略实现类的区别 主要是 juc包下的
         *
         *
         *    面试  :一个线程池 core 7; max 20 ,queue:50,100 并发进来怎么分配的;
         *    先有 7 个能直接得到执行,接下来 50 个进入队列排队,在多开 13 个继续执行。
         *    现在 70 个 被安排上了。剩下 30 个默认拒绝策略。
         *
         *    一般拒绝策略都是直接丢弃任务
         *    如果不想抛弃任务
         *    但RejectedExecutionHandler 的有一个实现类 CallerRunsPolicy
         *    这个类只要线程池没关 就可以调用 Runnable 的  run方法
         *     Runnable 的  run方法 是一个同步方法  想要异步需要 new Thread(Runnable).start()
         */
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,
                200,
                10,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(100000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

        //常见的4种线程池
      //  Executors.newFixedThreadPool(); // 核心0 最大线程数Integer的最大值 所有都可以回收
      //  Executors.newCachedThreadPool(); //核心线程数=最大线程数 固定大小  都不可回收
        //Executors.newScheduledThreadPool();// 定时任务的线程池
        //Executors.newSingleThreadExecutor();// 核心线程数 和 最大线程数都是 1 后台从队列里获取任务 挨个执行
        // System.out.println("main.....end.....");
    }


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

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

    //接口的泛型就是方法返回值的类型
    public static class Callable01 implements Callable<Integer>{
        @Override
        public Integer call() throws Exception {
            System.out.println("当前线程id :"+Thread.currentThread().getId());
            int i = 10 /2;
            System.out.println("运行结果 :"+i);
            return i;
        }
    }

}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值