本文对Java任务调度、线程池、Spring抽象进行比较,阐述的比较零乱,但是入理。
Timer与ScheduledThreadPoolExecutor的比较:
1.Timer对调度的支持是基于绝对时间的,因此任务对系统时间的改变是敏感的;而ScheduledThreadPoolExecutor支持相对时间。
2.Timer使用单线程方式来执行所有的TimerTask,如果某个TimerTask很耗时则会影响到其他TimerTask的执行;而ScheduledThreadPoolExecutor则可以构造一个固定大小的线程池来执行任务。
3.Timer 不会捕获由TimerTask抛出的未检查异常,故当有异常抛出时,Timer会终止,导致未执行完的TimerTask不再执行,新的 TimerTask也不能被调度;ScheduledThreadPoolExecutor对这个问题进行了妥善的处理,不会影响其他任务的执行。
关于ScheduledExecutorService与ExecutorService区别:
1.Executors类通过工厂方法返回ExecutorService接口的实现类如下:
newFixedThreadPool
newSingleThreadExecutor
newCachedThreadPool(常用)
2.返回ScheduledExecutorService接口的实现类:
newScheduledThreadPool,它返回的值ScheduledExecutorService extends ExecutorService。
3.二者的区别是ExecutorService是线程池的抽象。ScheduledExecutorService可以理解为线程池+调度的抽象。它在ExecutorService基础上多了schedule的功能。
工厂方法返回的ScheduledExecutorService与ExecutorService接口的实例底层实现都是ThreadPoolExecutor。
Spring2.*与Spring3对线程池,调度器,任务的封装:
Spring2.*提供了对concurrent包里线程池的封装。这个封装接口为TaskExecutor,它的实现类命名规则是*TaskExecutor如下:
ThreadPoolTaskExecutor
ConcurrentTaskExecutor
......
Spring2.*针对调度器提供的封装是ScheduledExecutorTask,ScheduledExecutorFactoryBean
Spring3对TaskExecutor的支持没变,另外,提供了新的TaskScheduler接口做为调度器的抽象; Trigger;注解;支持cron。Spring3可以用来取代quartz 80%的功能,所以,要在二者之间进行取舍。以往如果用到cron,都是使用quartz的封装。
关于Spring3中的任务调度:
一.@Scheduled
@Scheduled(fixedDelay=30000)
public void process(){
........
}
@Scheduled会做下面二件事情:
1.新建TaskScheduler实例(Spring3对于任务高度的改进:新的内置TaskScheduler和Trigger机制提供完善的cron支持)
注:Spring2.*是通过创建一个ScheduledExecutorFactoryBean来构建一个调度类(这个类估计就是Spring3中的TaskScheduler,ScheduledExecutorFactoryBean本质是对ScheduledExecutorService封装,将来会往队列里注册Task任务,Spring2.*中只有TaskExecutor接口及实现类。还没有所谓的TaskScheduler接口及实现类)。
2.annotation-driven标签会使用一个Spring的TaskScheduler实例(第一步创建的实例)注册此方法(做为一个Task)并以30秒的固定延迟执行它
附1.:@Scheduled里面可以调用@Async。如果只调一次,就是二个Task。如果调用N次。就是1+N个Task交给TaskExecutor执行。
附2:In addition to the TaskExecutor abstraction, Spring 3.0 introduces a TaskScheduler with a variety of methods for scheduling tasks to run at some point in the future.
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);
}
二.@Async
@Async注解用来实现异步执行(异步的原理就是新起线程执行,主线程不用等待,继续执行),在annotation-driven标签的作用下,该类被代理所包装, work()方法实际上是被一个TaskExecutor实例调用的。
The @Async annotation can be provided on a method so that invocation of that method will occur asynchronously. In other words, the caller will return immediately upon invocation and "the actual execution of the method will occur in a task that has been submitted to a Spring TaskExecutor". 这种是会在运行时,动态封装成一个Task交给TaskExecutor执行。 @Async不会象@Scheduled提供延迟,间隔等参数。它只表示异步。
@Scheduled修饰的方法会被容器调用,所以它修饰的方法不需要参数。容器也无法传不同的参。而@Async修饰的方法由于多数不是被容器管理,而是在应用程序中被调用者调用,所以可以加参数:these methods can expect arguments, because they will be invoked in the "normal" way by callers at runtime rather than from a scheduled task being managed by the container.
示例:
@Async
void Dosomething(String s) {
// this will be executed asynchronously
}
Even methods that return a value can be invoked asynchronously. However, such methods are required to have a Future typed return value. This still provides the benefit of asynchronous execution so that the caller can perform other tasks prior to calling get() on that Future.
@Async
Future<String> returnSomething(int i) {
// this will be executed asynchronously
}
小结:
@Scheduled修饰的方法调用@Async修饰的方法。如果只调一次,就是二个Task。如果调用N次。就是1+N个Task交给TaskExecutor执行。
Spring3里面使用TaskExecutor执行Task队列(@Scheduled修饰的方法会被加入到Task队列)。@Async修饰的方法被动态封装的Task并提交给TaskExecutor执行。
零碎的知识点:
1.Executor=线程池
2.使用多线程时,尽量做到与线程上下文传递无关,通常放到调用链的最底层。比如hibernate的session是绑定到线程变量上的,在多线程的情况下,新线程会由于不是同一session而无法lazyload.
3.异步的一个主要实现就是新起线程执行,主线程不用等待。 ScheduledThreadPoolExecutor较Timer的一个优势就是线程池异步执行。Timer由于是单线程执行队列。肯定没有前者快。
转自: http://www.blue1000.com/bkhtml/2010-10/69431.htm