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

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

使用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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值