ThreadPoolExecutor 自定义线程池

之前由于工作比较忙就随便写了一下线程池方面的面试回答,非常简陋,今天回首看了看是如此的不堪入目,于是乎激发了我重新整理一遍的决心.

 关于线程的使用,做开发的不会还有人不知道怎么使用吧?  呐,入下图所示就是最简单的线程使用

是不是觉得很简单

这得从google 创造Thread 对象的时候说起.

话说从前google创建Thread的时候无论是创建Thread对象还是销毁Thread对象都会消耗cpu资源,而且线程的运行是抢占式的,某个时间段那个线程抢到执行权就会先执行事件线程一多就会出现相互抢占的情况,而且同一时刻也会出现多个线程抢着关闭的情况.这里只是说会存在这种情况不是一定会出现这种情况(语文不好的同学不要钻牛角尖),那出现这种情况是不是就会抢占cpu资源,嘿嘿

书接上回  也就是上边

既然存在这种情况,那google爸爸可就不能不管了,于是乎google 就提供了Executors 类提供四个现成的线程池他们分别是

SingleThreadPool          核心线程和非核心线程都是1  无超时限制不会被回收

CacheThreadPool        无核心线程.非核心线程数Integer最大值  有存活时间限制,超时直接回收

FixedThreadPool          核心线程和非核心线程一至  空闲不会被回收

ScheduleThreadPool    核心线程大小有限制.非核心线程Integer最大值 空闲直接回收

 

好了现在轮到线程池大佬出场了,主要你有点进去看过这四个线程池里边的实现源码你就会发现,其实他们都是通过 ThreadPoolExecutor 进行创建的,

对,没错,自定义线程池就得用到ThreadPoolExecutor

ThreadPoolExecutor的几个参数

corePoolSize           核心线程大小

maximunPoolSize      非核心线程大小

keepAliveTime         保留时间

TimeUnit               时间单位

BlockingQueue         事件队列

ThreadFactory          线程工厂

RejectedExecuttionHandler  任务队列已满回调策略

 现在大概明白线程池是个什么东东了吧

定义IO/CPU密集型线程池 就需要根据CPU的进程数进行参数配置

将 corePoolSize 和 maximumPoolSize都设置成  CPU进程数 * 2 + 1 即可

CPU进程数获取

Runtime.getRumtime().availableProcessors()

em....... 就说到这里了,更加详细的ThreadPool自定义可以看看下边这个大佬写的,可以说是相当详细了

package com.nova.lib.util

import android.os.Build
import androidx.annotation.RequiresApi
import com.nova.base.util.log.LogUtil
import java.util.concurrent.LinkedBlockingDeque
import java.util.concurrent.RejectedExecutionHandler
import java.util.concurrent.ThreadFactory
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger

@RequiresApi(Build.VERSION_CODES.N)
object ThreadPoolUtil {

    private val TAG = "ThreadPoolUtil"

    private val CPU_COUNT = Runtime.getRuntime().availableProcessors()
    private val corePoolSize = CPU_COUNT * 2 + 1
    private val maximumPoolSize = CPU_COUNT * 2 + 1

    //    private val keepAliveUnit =
    private val keepAliveTime = 60L
    lateinit var threadPoolExecutor: ThreadPoolExecutor


    fun execute() {
        if (!this::threadPoolExecutor.isInitialized) {
            threadPoolExecutor = ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                TimeUnit.SECONDS,
                LinkedBlockingDeque(),
                MyThreadFactory()
            ) { runnable, threadPoolExecutor ->
                if (!threadPoolExecutor.isShutdown) {
                    // 尝试移除队列头部任务,然后再重新添加到队列
                    threadPoolExecutor.queue.poll()
                    threadPoolExecutor.execute(runnable)
                }
                LogUtil.d(TAG, "线程池异常收集 ")
            }
        }
        // 线程池定义的四种拒绝策略
        // ThreadPoolExecutor.AbortPolicy 抛出异常
        // ThreadPoolExecutor.CallerRunsPolicy  循环重试
        // ThreadPoolExecutor.DiscardPolicy 丢弃无法执行的任务
        // ThreadPoolExecutor.DiscardOldestPolicy 移除队列头部任务,并执行当前任务

    }


    class MyThreadFactory : ThreadFactory {
        var atomicInteger = AtomicInteger()
        val name = "-io-"

        override fun newThread(p0: Runnable?): Thread {
            return Thread(p0, "${ContextUtil.topAct}$name${atomicInteger.getAndIncrement()}")
        }
    }


}

一位靓仔博主总结得不错哦

Java并发编程:线程池的使用 - Matrix海子 - 博客园

关于线程池(并发)使用会遇到的问题

面试官:你觉得用了多线程可能会出现什么问题?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值