java.lang.Thread
)被一对一的映射为本地操作系统线程:Java线程启动时会创建一个本地操作系统线程;该Java线程终止时,本地操作系统线程也会被回收。操作系统会调度所有线程并把他们分配给可用的CPU。Executor框架主要由三部分组成:
Executors.callable(Runnable task)
或者Executors.callable(Runnable task, Object result)
转化为Callable对象。ExecutorService接口
。Executor框架有两个关键类ThreadPoolExecutor类
和ScheduledThreadPoolExecutor类
,实现了ExecutorService接口。ScheduledThreadPoolExecutor类
继承了ThreadPoolExecutor类
,并实现了ScheduledExecutorService接口
。ScheduledExecutorService接口
又实现了ExecutorService接口
。Future接口
和实现了Future接口的FutureTask类
。ExecutorService.submit()方法
)提交给ThreadPoolExecutor
或者ScheduledThreadPoolExecutor
去执行,会返回一个FutureTask对象。Executor框架主要成员的介绍:
Executor接口:
Executor框架的基础,将任务的提交和任务的执行分离。ThreadPoolExecutor类:
Java线程池的核心实现类,用来执行提交的任务。ScheduledThreadPoolExecutor类:
Executor框架的另一个关键类,可以在给定的延迟后执行命令,或者定期执行命令。Future接口
、FutureTask类
、Runnable接口
、Callable接口
。Executors.callable(Runnable task)
或Executors.callable(Runnable task,Object result)
。ThreadPoolExecutor.execute(Runnable command)
或者ScheduledThreadPoolExecutor.execute(Runnal command)
;或者也可以把Runnable对象或Callable对象提交给ExecutorService执行,方法:ExecutorService.submit(Runnable task)
或ExecutorService.submit(Callable task)
。execute()方法
用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功;submit()方法
用于提交需要返回值的任务,线程池会返回一个FutureTask类型的对象,通过这个FutureTask对象可以判断任务是否执行成功。FutureTask.get()方法
或者FutureTask.get(long timeout, TimeUnit unit)方法
来获取返回值。其中,前者会阻塞当前线程直到任务完成;后者,会阻塞当前线程一段时间后立即返回,有可能任务并没有执行完成。FutureTask.get()方法
来等待任务执行完成。主线程也可以执行FutureTask.cancel(boolean mayInterruptIfRunning)
来取消任务的执行。FixedThreadPool
Executors.newFixedThreadPool(threadsNum)
。public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
SingleThreadExecutor
Executors.newSingleThreadExecutor()
。public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
CachedThreadPool
Executors.newCachedThreadPool()
。public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
ScheduledThreadPool
Executors.newScheduledThreadPool(corePoolSize)
。public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
SingleThreadScheduledExecutor
Executors.newSingleThreadScheduledExecutor()
。public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}
corePoolSize = maximumPoolSize = newFixedThreadPool(num)方法的参数num
,实际只使用了corePool。keepAliveTime
的值为0L,表明工作线程如果空闲会被立即终止。LinkedBlockingQueue
,这是一种基于链表的无界队列,因为队列容量为Integer.MAX_VALUE
。队列中的元素采用FIFO序。shutdown()或者shutdownNow()方法
的情况下,不会调用饱和策略。corePoolSize
满时,由于使用无界队列,新提交的任务总是可以存放在阻塞队列中。因此,线程池中的线程数永远不会超过corePoolSize
。maximumPoolSize
参数无效。keepAliveTime
参数无效。shutdown()或者shutdownNow()方法
的情况下,不会调用饱和策略(即不会RejectExecutionHandler.rejectExecution()
方法)。corePoolSize
,则创建新的线程来执行任务;corePoolSize
,将任务加入LinkedBlockingQueue
;LinkedBlockingQueue
中获取任务来执行;corePoolSize = maximumPoolSize = 1
,实际只使用了corePool。keepAliveTime
的值为0L,表明工作线程如果空闲会被立即终止。LinkedBlockingQueue
,基于链表的无界队列,队列中的元素采用FIFO顺序。shutdown()或者shutdownNow()方法
的情况下,不会调用饱和策略。LinkedBlockingQueue
中。LinkedBlockingQueue
中取出任务来执行。SingleThreadExecutor
线程池中同时最多只有一个线程活跃,同时最多只有一个任务在执行。corePoolSize = 0
,maximumPoolSize = Integer.MAX_VALUE
,表明线程池无界,实际只使用了maximumPool。keepAliveTime
的值为60s,表明工作线程最多允许空闲60s,超过60s会被终止。SynchronousQueue
,是一种没有容量的阻塞队列,主线程的每个添加操作必须等待另一个线程的移除操作,反之亦然。Synchronous.offer()
,即添加操作。如果当前maximumPool中有空闲线程正在执行SynchronousQueue.poll(keepAliveTime,TimeUnit.NANOSECONDS)
(即移除操作),那么主线程的offer操作和空闲线程的poll操作配对成功,主线程把任务交给空闲线程执行。SynchronousQueue.poll(keepAliveTime,TimeUnit.NANOSECONDS)
,这个poll操作会让空闲线程等待60秒。如果60秒内主线程发起了offer操作,这个空闲线程便会执行主线程新提交的任务;否则,这个空闲线程将会终止。corePoolSize = Executors.newScheduledThreadPool(num)中的参数
,ScheduledThreadPool的参数大于等于1,而SingleThreadScheduledExecutor的参数为1。maximumPoolSize = Integer.MAX_VALUE
,实际只使用了corePool。keepAliveTime
的值为0L,表明线程一旦空闲就会被终止。DelayQueue
,这是一个具有优先级的无界队列,内部封装了一个PriorityQueue
,可以实现任务的定期执行和延后执行。shutdown()或者shutdownNow()方法
的情况下,不会调用饱和策略。ScheduledThreadPoolExecutor
的 scheduleAtFixedRate() 方法
或者scheduleWithFixedDelay() 方法
时,会向DelayQueue
添加一个实现了 RunnableScheduledFuture 接口
的 ScheduledFutureTask
。DelayQueue
中获取ScheduledFutureTask
,然后执行任务。执行任务周期的步骤,或者如何实现任务周期执行的?
大于等于
当前系统的时间,表明该任务已到期,可以执行。ScheduledThreadPoolExecutor
的序号。DelayQueue.take()方法
从DelayQueue中获取已经到期的ScheduledFutureTask
。到期任务是指ScheduledFutureTask
的time小于等于当前系统的时间。if (first == null || first.getDelay(NANOSECONDS) > 0)
return null;
ScheduledFutureTask
。ScheduledFutureTask
中的time为下次将要被执行的时间。ScheduledFutureTask
使用DelayQueue.add()方法
,放回到DelayQueue中。1. 说一下常见的四种线程池及区别
2. 线程池的底层实现?