• 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
    
  • 相关阅读:
    Spring异步调用注解@Async的使用
    maven 打包前 Junit 测试
    windows 访问局域网共享文件
    IBM MQ 集成CXF 发送JMS 消息
    VO、DTO、DO、PO的概念、区别和用处
    myeclipse创建的项目发布不了文档
    js获取jsp上下文地址
    Maven编译时,出现找不到符号
    Cause: java.lang.ClassCastException: java.lang.String cannot be cast to org.apache.ibatis.mapping.MappedStatement
    使用IDEA从github中下载fastdfs-client-java
  • 原文地址:https://www.cnblogs.com/umgsai/p/5671668.html
Copyright © 2020-2023  润新知