Java并发编程核心方法与框架-ScheduledExecutorService的使用

类ScheduledExecutorService的主要作用是可以将定时任务与线程池功能结合。

使用Callable延迟运行(有返回值)
public class MyCallableA implements Callable<String> {

	@Override
	public String call() throws Exception {
		try {
			System.out.println("MyCallableA.call() begin " + Thread.currentThread().getName() + System.currentTimeMillis());
			Thread.sleep(3000);
			System.out.println("MyCallableA.call() end " + Thread.currentThread().getName() + System.currentTimeMillis());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "returnB";
	}
}

public class MyCallableB implements Callable<String> {

	@Override
	public String call() throws Exception {
		System.out.println("MyCallableB.call() begin " + Thread.currentThread().getName() + System.currentTimeMillis());
		System.out.println("MyCallableB.call() end " + Thread.currentThread().getName() + System.currentTimeMillis());
		return "returnA";
	}
}

public class Main {
	public static void main(String[] args) {
		try {
			List<Callable<String>> callables = new ArrayList<>();
			callables.add(new MyCallableA());
			callables.add(new MyCallableB());
			int corePoolSize = 2;
			ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(corePoolSize);
			long delay = 4;//延迟4秒开始执行
			TimeUnit unit = TimeUnit.SECONDS;
			ScheduledFuture<String> scheduledFutureA = scheduledExecutorService.schedule(callables.get(0), delay, unit);
			ScheduledFuture<String> scheduledFutureB = scheduledExecutorService.schedule(callables.get(1), delay, unit);
			System.out.println("x=" + System.currentTimeMillis());//x=1473037234998
			System.out.println("A:" + scheduledFutureA.get());//阻塞,等待任务返回结果
			System.out.println("B:" + scheduledFutureB.get());
			System.out.println("y=" + System.currentTimeMillis());//y=1473037242004
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

运行以上代码,控制台输出结果如下:

x=1473037234998
MyCallableA.call() begin pool-1-thread-11473037238999
MyCallableB.call() begin pool-1-thread-21473037238999
MyCallableB.call() end pool-1-thread-21473037238999
MyCallableA.call() end pool-1-thread-11473037242004
A:returnB
B:returnA
y=1473037242004

以上结果为异步执行效果。对main函数进行如下修改:

public class Main {
	public static void main(String[] args) {
		try {
			List<Callable<String>> callables = new ArrayList<>();
			callables.add(new MyCallableA());
			callables.add(new MyCallableB());
			int corePoolSize = 2;
			//ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(corePoolSize);
			//单个线程
			ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
			long delay = 4;//延迟4秒开始执行
			TimeUnit unit = TimeUnit.SECONDS;
			ScheduledFuture<String> scheduledFutureA = scheduledExecutorService.schedule(callables.get(0), delay, unit);
			ScheduledFuture<String> scheduledFutureB = scheduledExecutorService.schedule(callables.get(1), delay, unit);
			System.out.println("x=" + System.currentTimeMillis());//x=1473038300975
			System.out.println("A:" + scheduledFutureA.get());
			System.out.println("B:" + scheduledFutureB.get());
			System.out.println("y=" + System.currentTimeMillis());//y=1473038307984
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

此时控制台打印结果如下:

x=1473038300975
MyCallableA.call() begin pool-1-thread-11473038304979
MyCallableA.call() end pool-1-thread-11473038307984
A:returnB
MyCallableB.call() begin pool-1-thread-11473038307984
MyCallableB.call() end pool-1-thread-11473038307984
B:returnA
y=1473038307984

此时控制台执行效果为同步执行。方法中的delay参数在多个任务中同时消耗时间,并不是一个任务执行完毕之后再等4秒继续执行。

查看newSingleThreadScheduledExecutor方法源代码:

public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
    return new DelegatedScheduledExecutorService
        (new ScheduledThreadPoolExecutor(1));
}

实例化ScheduledThreadPoolExecutor时传入的参数是1,是单任务执行的计划任务池。


使用Runnable延迟运行(无返回值)
public class MyRunnableA implements Runnable {

	@Override
	public void run() {
		try {
			System.out.println("MyRunnableA.run() begin " + Thread.currentThread().getName() + System.currentTimeMillis());
			Thread.sleep(3000);
			System.out.println("MyRunnableA.run() end " + Thread.currentThread().getName() + System.currentTimeMillis());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

public class MyRunnableB implements Runnable {

	@Override
	public void run() {
		System.out.println("MyRunnableB.run() begin " + Thread.currentThread().getName() + System.currentTimeMillis());
		System.out.println("MyRunnableB.run() end " + Thread.currentThread().getName() + System.currentTimeMillis());
	}
}

public class Main {
	public static void main(String[] args) {
		List<Runnable> runnables = new ArrayList<>();
		runnables.add(new MyRunnableA());
		runnables.add(new MyRunnableB());
		ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
		System.out.println("x=" + System.currentTimeMillis());
		int delay = 5;
		TimeUnit unit = TimeUnit.SECONDS;
		scheduledExecutorService.schedule(runnables.get(0), delay, unit);
		scheduledExecutorService.schedule(runnables.get(1), delay, unit);
		System.out.println("y=" + System.currentTimeMillis());
	}
}

执行结果如下:

x=1473039288190
y=1473039288191
MyRunnableA.run() begin pool-1-thread-11473039293196
MyRunnableA.run() end pool-1-thread-11473039296199
MyRunnableB.run() begin pool-1-thread-11473039296199
MyRunnableB.run() end pool-1-thread-11473039296199
posted @ 2016-07-14 20:33  商商-77  阅读(418)  评论(0)    收藏  举报