基于定时轮询获取异步的业务数据

业务场景:
要获取异步接口传来的数据进行项目内部的逻辑判断,但接口处理返回会与我们存在一个时间差。
基于现成的睡眠模式Thread. sleep(毫秒)也是可以实现,让我们的等待外部接口处理完,我们这边也睡眠完,再去查询我们想要的业务数据(但是 若我们睡眠完外部接口还是没有处理完成那我们如何定义这个睡眠时间点呢)

下面采用轮询的方式调用 若查到了就解除线程,若定义轮询n次还没查到,默认外部接口存在问题,下面上代码

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;

public class SyncPollingUtils {

	public static void main(String[] args) {
		try {
			new SyncPollingUtils().demo();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void demo() throws InterruptedException {
		//count为计数器的初始值(一般需要多少个线程执行,count就设为几)。
	    CountDownLatch countDownLatch = new CountDownLatch(1);
		//可被执行的任务,主要为定时任务的具体内容
		TimerTask task = new TimerTask() {
	        private int i = 0;
			@Override
	        public void run() {
				i++;
	            System.out.println("定时任务被执行了");
                if(i < 3) {
					//此处可以写业务逻辑,若是逻辑满足可以直接跳出cancel,线程结束countDown
					
                	this.cancel();
					//每调用一次计数器值-1,直到count被减为0,代表所有线程全部执行完毕。
                	countDownLatch.countDown();
                }else{
					//若是循环大于3次,也执行结束
					this.cancel();
					//每调用一次计数器值-1,直到count被减为0,代表所有线程全部执行完毕。
                	countDownLatch.countDown();
				}         
	        }
	    };
	    Timer timer = new Timer();
		//一秒后执行,每三秒执行一次		
	    timer.schedule(task, 1000, 3000);
		/*
		等待计数器变为0,即等待所有异步线程执行完毕。
		boolean await(long timeout, TimeUnit unit): 此方法与await()区别:
		①此方法至多会等待指定的时间,超时后会自动唤醒,若 timeout 小于等于零,则不会等待
		②boolean 类型返回值:若计数器变为零了,则返回 true;若指定的等待时间过去了,则返回 false
		*/
	    countDownLatch.await();
	    System.out.println("定时结束");
	}
}

额外: 如果编译器下载了阿里规约会出现此问题,说明阿里认为timer对代码来说,使用不是很健壮可以用ScheduledExecutorService
基于定时轮询获取异步的业务数据_第1张图片

首先看下两种调用方式
基于定时轮询获取异步的业务数据_第2张图片

优化后可以看下此代码的scheduleWithFixedRate写法

CountDownLatch countDownLatch = new CountDownLatch(1);
			ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
					new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());
			executorService.scheduleAtFixedRate(new Runnable() {
				private int i = 0;
				@Override
				public void run() {
					i++;
					log.info("定时任务被执行了");
					if(i < 11) {
						//此处可以写业务逻辑,若是逻辑满足可以直接跳出shutdown,线程结束countDown
						executorService.shutdown();
						countDownLatch.countDown();
					}else {
						executorService.shutdown();
						countDownLatch.countDown();
					}
				}
			},3000, 2000, TimeUnit.MILLISECONDS);
			countDownLatch.await();

你可能感兴趣的:(java,经验分享)