我有5个@Scheduled注释的方法,我的ThreadPoolTaskScheduler的池大小为10。我的方法的注释相同且如此。
@Scheduled(fixedDelay = 1000,initialDelay = 10000)
我的问题是
当调度的方法之一从池中获取线程并开始运行时;它在执行完成之前将线程释放到池中吗? (例如,在进行上下文切换等情况下)还是使用该线程直到执行结束?
我的意思是,计划任务的某些部分可能是由线程1完成的,而另一部分是由线程2完成的?
答案 0 :(得分:2)
线程很复杂,我的理解不如其他人,但是这里是我对@Scheduled
Spring注释的工作原理的简要说明:
Spring使用TaskScheduler
:
public interface TaskScheduler {
ScheduledFuture schedule(Runnable task, Trigger trigger);
ScheduledFuture schedule(Runnable task, Date startTime);
ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);
ScheduledFuture scheduleAtFixedRate(Runnable task, long period);
ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
}
将带注释的代码(即任务代码)提交给称为执行程序的高级并发对象。执行程序类为ThreadPoolTaskExecutor
。该类将任务提交到线程池,以由该池中的第一个可用线程运行。您设置的线程池大小决定了您可以拥有多少个活动线程。如果将allowCoreThreadTimeOut
设置为true
,则池中在其超时间隔内无法进行工作的线程将被终止。
Spring使用ThreadPoolTaskExecutor
来管理线程池:
使线程池保持活动状态可以减少通常在等待创建线程时添加的时间。有关更多信息,请参见此question。
最终,java.lang.Thread
类将运行ThreadPoolTaskExecutor
创建的Runnable或Callable实例。 Thread
类实现了一个run()
方法,该方法基本上就是您希望线程运行的代码:
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
...
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/lang/Thread.java
线程之间的实际切换,即上下文切换is OS-dependent,但通常在CPU之间分配线程,然后每个CPU根据超时间隔在线程之间循环,并做一些工作,然后暂停并暂停。在线程之间连续切换,直到任务完成。
它是否在执行完成之前将线程释放到池中? (例如在上下文切换等情况下)或使用此线程 直到执行结束?
Runnable代码肯定可以在操作过程中停止执行,但是线程池中的线程通常保持活动状态,直到没有更多工作要做。
Oracle documentation的更多信息介绍了线程池:
java.util.concurrent中大多数执行器实现 线程池,由工作线程组成。这种线 与它执行的Runnable和Callable任务分开存在,并且 通常用于执行多个任务。
使用工作线程可以最大程度地减少线程创建所带来的开销。 线程对象占用大量内存,并且在 大型应用程序,分配和取消分配多个线程 对象会产生大量的内存管理开销。
一种常见的线程池类型是固定线程池。这类 池始终有指定数量的正在运行的线程;如果一个线程是 在某种程度上终止使用时,它会自动 用新线程替换。任务通过 内部队列,每当有更多活动时,它就会容纳额外的任务 任务胜于线程。
固定线程池的一个重要优点是应用程序 使用它会降级。要了解这一点,请考虑使用Web服务器 每个HTTP请求由单独的线程处理的应用程序。 如果应用程序只是为每个新HTTP创建一个新线程 请求,系统收到的请求超出其处理能力 立即,应用程序将突然停止响应所有 当所有这些线程的开销超出最大容量时请求 系统。限制可以使用的线程数 创建后,该应用程序将无法处理HTTP请求,因为 它们一进入就很快,但是它将尽快为他们提供服务 系统可以维持。