• java基础---多线程---JUC线程池


    ===參考論文
     
     
    =====使用线程池有哪三个好处呢?
    1.重复使用线程,减少线程创建和销毁的消耗。
    2.提高响应速度。因为线程已经事先建好了,任务来了可以直接使用,减少响应的时间。
    3.提高线程可管理性。线程是稀缺资源不能够无线创建,通过线程池可以高效管理分配。
     
    =====一个任务提交到线程池了后会经过哪些处理步骤呢?
    1.先看线程池中的核心线程池。没有满的话新建线程处理任务。
    2.再看工作队列。如果工作队列没满,将任务提交到这个队列中。
    3.如果队列也满了,但是线程池没满,就创建线程处理任务。
    4.如果整个线程满了,就执行拒绝策略处理来的请求。
     
     
    =====创建一个线程池的时候可以指定哪些参数呢?阻塞队列有哪些以及具体应用?拒绝策略有哪些呢?
    1.核心线程数量
    2.最大线程数量
    3.线程空闲存活时间
    4.阻塞队列
    5.拒绝策略
    6.线程创建工厂Factory
     
     
    ---阻塞队列包括:
    数组阻塞队列(固定大小先进先出)
    链表阻塞队列(基于链表,先进先出,newFixedThreadPool就是用这个实现的)
    同步阻塞队列(不存储元素,每次插入必须有另一个线程做移除,吞吐量高,newCachedThreadPool)
    优先级阻塞队列(具有优先级的无线阻塞队列)。
     
    -----拒绝策略:抛异常,直接放弃任务,删除掉队列中最老的记录,然后执行当前任务,或者使用提交任务的线程执行任务。
     
     
    ===向线程池提交任务的方式有几种呢?
    分别是execute()和submit(),execute不返回结果,所以执行runnable接口;submit有返回值,能够返回future对象。
    execute没有返回值,不知道任务是否执行成功
    submit返回一个future对象,通过get方法可以通过阻塞的去获取任务的执行结果
    ExecutorService pool = Executors.newFixedThreadPool();
    pool.execute(new Runnable(){});
    Future future = pool.submit(Callable);
     
    ===什么是future模式
    如果一个很耗时的任务需要执行,而且这个返回值不是立刻需要的时候,就可以使用FutureTask去重新启动一个线程去执行,然后使用Future.get()来获取结果,这就是Future模式。
    //使用FutureTask去承载一个Callable要执行的任务
    FutureTask<Integer> futureTask = new FutureTask<Integer>(callable);
    //使用线程去执行,因为FutureTask实现了Runnable所以可以放到一个线程中执行。
    new Thread(futureTask).start();
    //最后异步地去获取结果
    System.out.println(futureTask.get());
     
    ===对于cpu密集型任务和io密集型任务分别如何设置线程池线程大小呢?
    cpu密集,就是需要长时间的计算处理,线程数量可以少一些。
    io密集,那么线程等待结果的时间会比较长,cpu空闲时间就长,所以线程数量可以相对多一些。
     
     
    ===有界队列和无界队列要选择哪种比较好呢?
    尽量使用有界队列。有界队列可以实现系统的稳定性,但是可以尽量设置大一点,几千。
    如果设置成无界队列,那么线程池的队列就会越来越多,内存会溢出,导致整个系统 崩溃,会波及到其他的任务。
     
    =====java中本身提供的线程池具体实现有哪两大类呢?有什么区别呢?
    具体有ThreadPoolExecutor和ScheduledThreadPoolExecutor
    1.区别就是后者使用了延迟队列DelayedQueue延迟队列,加入了一定的延迟和定时效果。
     
    =====ThreadPoolExecutor有哪三种具体的实现呢?
    第一种:FixedThreadPool可重用固定线程池线程固定,使用链表阻塞队列,所以阻塞的任务可以无限制的插入到队列中,也就是说线程最大值,线程存活时间,线程拒绝策略这些参数都是没有用的。适用于资源有限制,线程数量有限制的负载比较重的场景。
    第二种:SingleThreadExecutor单一线程,核心线程数和最大线程数都是1,使用链表阻塞队列,只有一个线程处理任务,适用于顺序处理任务的情况
    第三种:CachedThreadPool,线程无数会根据需要创建线程的线程池。核心数为0,最大值无穷大,可以根据任务实际情况来创建和销毁线程。线程空闲时间60s,使用没有容量的同步队列来作为阻塞队列,这种阻塞队列必须先执行掉一个任务才能够插入一个任务。一个任务提交进来,如果有空闲的线程,那么就直接执行任务,如果没有空闲的就创建新的线程去执行。适用于执行很多短期异步任务的情况,负载教轻的场景。
     
    =====ScheduledThreadPoolExecutor介绍?
    底层使用延迟队列DelayedQueue来保存任务,延迟队列通过优先队列来具体的保存任务的。一个任务提交进来会进行ScheduleFutureTask的封装,任务有编号,执行的时间,执行的周期三个参数。
    具体的执行过程:线程会获取到时的任务并且执行,然后修改任务下次执行时间重新插入到队列中。
     
     
    ===线程池的生命周期和线程池状态,简述线程池的五种状态?
    使用AtomicInteger的参数来记录线程池的状态ctl
    ctl共包括32位。其中,高3位表示"线程池状态",低29位表示"线程池中的任务数量"。
    running---接受新任务,处理旧任务,处理中的继续处理
    shutdown---不接受新任务,处理旧任务,处理中的继续处理
    stop---不接受新任务,不处理旧任务,处理中的中断
    tidying---整理状态,就是当任务数量为0,队列为空的时候,从shutdown状态进入到整理状态。
    terminated---终止状态,从tidying执行terminate()方法之后进入的状态。
     
  • 相关阅读:
    Redis 读后小感
    Redis学习笔记十:独立功能之监视器
    Redis学习笔记九:独立功能之慢查询日志
    Redis学习笔记八:独立功能之二进制位数组
    Please restart this script from an administrative PowerShell
    MSBUILD : error MSB3428: 未能加载 Visual C++ 组件“VCBuild.exe”
    Macaca之Android原理浅析
    Macaca 基础原理浅析
    您需要来自XXX的权限才能对此文件夹进行更改
    JS是按值传递还是按引用传递?
  • 原文地址:https://www.cnblogs.com/buptyuhanwen/p/9546800.html
Copyright © 2020-2023  润新知