线程池7大参数,三大方法,四大拒绝策略

Java线程具有五中基本状态

线程池7大参数,三大方法,四大拒绝策略_第1张图片

新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就     绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:

1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

为什么要使用线程池?

线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后再线程创建后启动这些任务如果线程的数量超过最大数量,超过数量的线程将排队等候,等其他线程执行完毕,再从队列中取出任务来执行

特点:线程复用,控制最大并发数,管理线程

一、降低资源消耗,通过重复利用已创建的线程降低线程创建和销毁造成的消耗

二、提高响应速度,当任务到达时,任务可以不需要的等到线程创建就能够立刻执行

三、提高线程的可管理性,线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,

还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

线程池创建的核心:

   1、七大参数:

  • corePoolSize:线程池核心线程数量,核心线程不会被回收,即使没有任务执行,也会保持空闲状态。如果线程池中的线程少于此数目,则在执行任务时创建。
  • maximumPoolSize:池允许最大的线程数,当线程数量达到corePoolSize,且workQueue队列塞满任务了之后,继续创建线程。
  • keepAliveTime:超过corePoolSize之后的“临时线程”的存活时间。
  • unit:keepAliveTime的单位。
  • workQueue:当前线程数超过corePoolSize时,新的任务会处在等待状态,并存在workQueue中,BlockingQueue是一个先进先出的阻塞式队列实现,底层实现会涉及Java并发的AQS机制,有关于AQS的相关知识,我会单独写一篇,敬请期待。
  • threadFactory:创建线程的工厂类,通常我们会自顶一个threadFactory设置线程的名称,这样我们就可以知道线程是由哪个工厂类创建的,可以快速定位。
  • handler:线程池执行拒绝策略,当线数量达到maximumPoolSize大小,并且workQueue也已经塞满了任务的情况下,线程池会调用handler拒绝策略来处理请求。

    2、四大拒绝策略:

  • AbortPolicy:为线程池默认的拒绝策略,该策略直接抛异常处理。
  • DiscardPolicy:直接抛弃不处理。
  • DiscardOldestPolicy:丢弃队列中最老的任务。
  • CallerRunsPolicy:将任务分配给当前执行execute方法线程来处理。

3、三大方法

           1.Executors.newSingleThreadExecutor();
           2.Executors.newFixedThreadPool(5);
           3.Executors.newCachedThreadPool();

4、线程池最大值如何设置:


      1.CPU密集型
           System.out.println(Runtime.getRuntime().availableProcessors());
           获得cpu的核数,不同的硬件不一样
      2.IO密集型
          大型的程序任务有多少个? IO非常消耗资源
          线程池最大值 > 大型任务的数量即可
          一般设置大型任务的数量*2

//手写线程池
public class MyThreadPoolDemo {
    public static void main(String[] args) {
        System.out.println(Runtime.getRuntime().availableProcessors());

        ExecutorService threadPool = new ThreadPoolExecutor(
                2, //corePoolSize
                5,//maximumPoolSize
                1L,//keepAliveTime
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );

     try
    {
        //模拟10个用户来办理业务,每个用户就是来自外部的请求线程
        for (int i = 1; i <= 10; i++) {

            threadPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + "\t 办理业务");
            });
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally{
        threadPool.shutdown();
    }
}}


      

你可能感兴趣的:(线程池)