您的位置:首页 > 编程语言 > Java开发

Java任务调度和线程池理解

2013-04-29 20:27 281 查看
Java任务调度实现方法:
Timer,Scheduler

1、Timer

Timer类是用来执行任务的类,它接受一个TimerTask做参数

建立任务:使用Timer调度的任务应该继承TimerTask抽象类,该类实现Runnable接口,因些具备多线程的能力,实现该接口的run方法,该方法是需要高度的任务执行体。

调度任务:调度任务通过Timer类完成,调度任务通过schedul方法完成

Timer有两种执行任务的模式,最常用的是
schedule,它可以以两种方式执行任务:1:在某个时间(Data),2:在某个固定的时间之后(int
delay).这两种方式都可以指定任务执行的频率.看个简单的例子:

import java.io.IOException;
import java.util.Timer;

public class TimerTest {
public static void main(String[] args){
Timer timer = new Timer();
timer.schedule(new MyTask(), 1000, 2000);//在1秒后执行此任务,每次间隔2秒,如果传递一个Data参数,就可以在某个固定的时间执行这个任务.
while(true){//这个是用来停止此任务的,否则就一直循环执行此任务了
try {
int ch = System.in.read();
if(ch-'c'==0){
timer.cancel();//使用这个方法退出任务
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
static class MyTask extends java.util.TimerTask{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("$$$$$");
}
}
}
2.Scheduler

基于线程池设计的 ScheduledExecutor。其设计思想是,每一个被调度的任务都会由线程池中一个线程去执行,因此任务是并发执行的,相互之间不会受到干扰。需 要注意的是,只有当任务的执行时间到来时,ScheduedExecutor 才会真正启动一个线程,其余时间 ScheduledExecutor 都是在轮询任务的状态。

package com.ibm.scheduler;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledExecutorTest implements Runnable {
private String jobName = "";

public ScheduledExecutorTest(String jobName) {
super();
this.jobName = jobName;
}

@Override
public void run() {
System.out.println("execute " + jobName);
}

public static void main(String[] args) {
ScheduledExecutorService service = Executors.newScheduledThreadPool(10);

long initialDelay1 = 1;
long period1 = 1;
// 从现在开始1秒钟之后,每隔1秒钟执行一次job1
service.scheduleAtFixedRate(
new ScheduledExecutorTest("job1"), initialDelay1,
period1, TimeUnit.SECONDS);

long initialDelay2 = 1;
long delay2 = 1;
// 从现在开始2秒钟之后,每隔2秒钟执行一次job2
service.scheduleWithFixedDelay(
new ScheduledExecutorTest("job2"), initialDelay2,
delay2, TimeUnit.SECONDS);
}
}


输出结果:

execute job1

execute job1

execute job2

execute job1

execute job1

execute job2

3.Timer与ScheduledThreadPoolExecutor的比较:

Timer对调度的支持是基于绝对时间的,因此任务对系统时间的改变是敏感的;而ScheduledThreadPoolExecutor支持相对时间。

 Timer使用单线程方式来执行所有的TimerTask,如果某个TimerTask很耗时则会影响到其他TimerTask的执行;而ScheduledThreadPoolExecutor则可以构造一个固定大小的线程池来执行任务。

 Timer 不会捕获由TimerTask抛出的未检查异常,故当有异常抛出时,Timer会终止,导致未执行完的TimerTask不再执行,新的 TimerTask也不能被调度;ScheduledThreadPoolExecutor对这个问题进行了妥善的处理,不会影响其他任务的执行。

4.注意

Executor=线程池

使用多线程时,尽量做到与线程上下文传递无关,通常放到调用链的最底层。比如hibernate的session是绑定到线程变量上的,在多线程的情况下,新线程会由于不是同一session而无法lazyload.

异步的一个主要实现就是新起线程执行,主线程不用等待。  ScheduledThreadPoolExecutor较Timer的一个优势就是线程池异步执行。Timer由于是单线程执行队列。肯定没有前者快。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: