当前位置: 首页 > 科技观察

如何手写线程池?

时间:2023-03-14 21:05:28 科技观察

手写一个异步工具类我是小智,我是新公司。这家公司有个特点,就是鼓励大家把各种实用的工具打包,提高开发效率。于是我翻了一下项目的源码,看看有没有可以改进的地方?果然,我找到了。该项目充满了新的Thread类来异步执行代码逻辑。新线程(r).start();我们可以封装一个异步工具类!第一个版本说到做到,简单的封装了上面的代码,封装了一个简单的异步工具类。publicinterfaceExecutor{voidexecute(Runnabler);}publicclassAsyncExecutorV1implementsExecutor{@Overridepublicvoidexecute(Runnabler){newThread(r).start();}}于是愉快的提交了合并请求。在第二版的时候,当我对工具代码合并充满期待的时候,没想到代码被组长杰哥退了回来。《杰哥》:工具的封装值得鼓励,但还是可以改进的。《小智》:可以改进吗?我认为我的工具类没有改进的余地!《杰哥》:假设有10000个异步任务,你创建10000个线程,资源消耗太严重了!“小智”:就是这样,那我就加一个队列,把所有的任务都放到队列里,用一个线程从队列中取任务执行。publicclassAsyncExecutorV2implementsExecutor{privateBlockingQueueworkQueue;publicAsyncExecutorV2(BlockingQueueworkQueue){this.workQueue=workQueue@;WorkThreadworkThread=newWorkThread();workThread.start();执行(可运行的r){workQueue.add(r);}classWorkThreadextendsThread{@Overridepublicvoidrun(){while(true){Runnabletask=null;尝试{task=workQueue.take();}catch(InterruptedExceptione){e.printStackTrace();}task.run();}}}}《小知识》第三版:杰哥,帮我看看,有没有进步?“杰哥”:好家伙,你可以想到用队列来缓冲任务,不愧是我招的人啊!但是使用异步线程来执行任务,你确定这个工具比同步执行速度快吗?《小知识》:哈哈,又一个工具类翻车的情况下,应该多开几个异步线程来执行任务,但是应该开多少个呢?《杰哥》:谁知道异步工具类应该用多少个线程来执行呢?《小知识》:使用工具类人。《杰哥》:这个不对,你可以定义一个线程数的参数,让用户自己决定开多少个线程。“另外,你的工具类还有一个问题,当队列满了,会直接抛出异常!”《小智》:那我就加一个拒绝策略类(RejectedExecutionHandler)。异常,使用当前线程同步执行任务。公共类AsyncExecutorV3实现执行器{privateBlockingQueueworkQueue;privateListworkThreadList=newArrayList<>();私有RejectedExecutionHandler处理程序;publicAsyncExecutorV3(intcorePoolSize,BlockingQueueworkQueue,RejectedExecutionHandlerhandler){this.workQueue=workQueue;this.handler=处理程序;for(inti=0;iworkQueue;privateListworkThreadList=newArrayList<>();私有RejectedExecutionHandler处理程序;publicAsyncExecutorV4(intcorePoolSize,BlockingQueueworkQueue,RejectedExecutionHandlerhandler,ThreadFactorythreadFactory){this.workQueue=workQueue;this.handler=处理程序;for(inti=0;iworkQueue,ThreadFactorythreadFactory,RejectedExecutionHandlerhandler)参数含义corePoolSize核心线程数maximumPoolSize最大线程数threadskeepAliveTime非核心线程空闲时间TimeUnit空闲时间单位BlockingQueue任务队列ThreadFactory线程工厂RejectedExecutionHandler拒绝策略《执行流程图如下》:顺便最后大家给这个异步工具类起个好听的名字,“线程池”。