一个线程从被提交(submit)到执行共经历以下流程:
-
线程池判断核心线程池里是的线程是否都在执行任务,如果不是,则创建一个新的工作线程来执行任务。如果核心线程池里的线程都在执行任务,则进入下一个流程
-
线程池判断工作队列是否已满。如果工作队列没有满,则将新提交的任务储存在这个工作队列里。如果工作队列满了,则进入下一个流程。
-
线程池判断其内部线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已满了,则交给饱和策略来处理这个任务。
-
任务拒接策略?
有4种内置的实现策略和一个用户自定义拒绝策略。
AbortPolicy 为java线程池默认的阻塞策略,不执行此任务,而且直接抛出一个运行时异常,切记ThreadPoolExecutor.execute需要try catch,否则程序会直接退出。
DiscardPolicy 直接抛弃,任务不执行,空方法 。
DiscardOldestPolicy 从队 列里面抛弃head的一个任务,并再次execute 此task。
CallerRunsPolicy 在调用execute的线程里面执行此command,会阻塞入口 。
用户自定义拒绝策略 实现RejectedExecutionHandler,并自己定义策略模式。
再次需要注意的是,ThreadPoolExecutor.submit() 函数,此方法内部调用的execute方法,并把execute执行完后的结果给返回,但如果任务并没有执行的话(被拒绝了),则submit返回的future.get()会一直等到。
future 内部其实还是一个runnable,并把command给封装了下,当command执行完后,future会返回一个值。