线程池理解

  1. ##线程池的好处
    频繁的创建线程,销毁线程,会造成很大的性能开销,线程池技术可以人为的控制线程池的创建和销毁,可以提前创建好线程,放在线程池中,需要的时候就获取。

  2. 线程池主要有以下几个属性构成
    corePoolSize:核心线程数
    maximumPoolSize:最大线程数
    keepAliveTime:线程空闲时间
    TimeUnit :空闲时间单位
    workQueue:等待队列

  3. 三种常用的线程池
    newCachedThreadPool:无界线程池,该类型的线程池的的核心线程池的数量为0 ,也就是说没有核心线程池,最大线程池的数量是Integer.Max_value,其队列是SynchronouseQueue。其特点就是只要有新的任务进来就创建新的线程,直到资源用尽。

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

newFixedThreadPool:有界线程池,有固定大小的核心线程池数量和最大线程池数量,其等待队列是LinkedBlockingQueue。其特点是,核心线程数和最大线程数都是一样的,但是等待队列可以无限增大,知道资源用尽。

 public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行

class ScheduledThreadDemo extends Thread{
    @Override
    public void run() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(df.format(System.currentTimeMillis()));
        System.out.println("正在运行的线程名字" + Thread.currentThread().getName());
    }

}
  public static void main(String[] args) {
        ExecutorService executorService4 = Executors.newScheduledThreadPool(1);
        ScheduledThreadDemo scheduledThreadDemo = new ScheduledThreadDemo();
        ((ScheduledExecutorService) executorService4).scheduleAtFixedRate(scheduledThreadDemo,5,5, TimeUnit.SECONDS);



4.几种常见的队列
SynchronousQueue:此策略可以避免在处理可能具有内部依赖性的请求集时出现锁,一般搭配的是没有核心线程,最大线程为无数,所以每次任务都会创建新的线程,任务先加在队列中,只有被线程取走任务才能加入新的任务。
LinkedBlockingQueue:无界队列,当任务数大于等于核心线程的时候,就可以无限把任务加到无界队列中。
ArrayBlockingQueue:有界队列,使用复杂,但是合理使用可以有效防止资源耗尽。

5.如何设定线程池线程数:
5.1:CPU密集型:本地逻辑运行,占用cpu比价多,线程数小一些
5.2:I/O密集型:网络调用,DB调用,缓存调用之类,线程数可以大些。因为需要等待时间,但是不占CPU.
如果业务不是很复杂,CPU密集型可以设置为N+1,IO密集型设置2N的线程数(Netty源码也是默认用的这个公式)。如果业务涉及很多业务逻辑,可以使用:线程数=N(CPU核数)*(1+(线程等待时间)/(线程时间运行时间)),这个除法公式的核心思想是等待时间占比越大,线程数就越大,尽量让多个线程去抢占运算资源,否则线程都IO阻塞了,浪费资源。
Runtime.getRuntime().availableProcessors()可以获取可使用的CPU数。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值