ScheduledExecutorService线程池实现支付通知回调

通知定时任务类: 

public class NotifyMCTimer implements Callable<String> {
	private Map<String,String> resultMap;
	private String trade_no;
	private String notifyUrl;
	private volatile int runTimes = 0; 
    public NotifyMCTimer(Map<String, String> resultMap, String notifyUrl, String trade_no) {
		super();
		this.resultMap = resultMap;
		this.notifyUrl = notifyUrl;
		this.trade_no = trade_no;
	}

	@Override
	public String call() throws Exception {
		return HttpUtils.sendPostMessage(resultMap, "utf-8", notifyUrl);
	}
	
	public Map<String, String> getResultMap() {
		return resultMap;
	}
	
	public void setResultMap(Map<String, String> resultMap) {
		this.resultMap = resultMap;
	}
	public String getTrade_no() {
		return trade_no;
	}
	
	public void setTrade_no(String trade_no) {
		this.trade_no = trade_no;
	}

	public int getRunTimes() {
		return runTimes;
	}

	public void setRunTimes(int runTimes) {
		this.runTimes = runTimes;
	}
}

发送定时任务工具类:

public class ScheduledExecutorServiceUtil extends BaseService {
	private volatile static ScheduledExecutorService scheduledExecutor ;  
	private static MyBlockingQueue<Callable<String>> queue ;
    private ScheduledExecutorServiceUtil (){}  
    //初始化
    public static void startUp() {  
	    if (scheduledExecutor  == null) {  
	        synchronized (ScheduledExecutorServiceUtil.class) {  
		        if (scheduledExecutor  == null) {  
		        	scheduledExecutor  = Executors.newScheduledThreadPool(10);
		        	queue = new MyBlockingQueue<>(100);
		    		new Consumer(queue).start();
		        }  
	        }  
	    }  
    } 
    //提交无延迟任务
    public static void submitNoDelay(Callable<String> task){
    	NotifyMCTimer timer = (NotifyMCTimer)task;
    	try {
	    	ScheduledFuture<String> future = scheduledExecutor.schedule(task, 0, TimeUnit.MILLISECONDS);
	    	timer.setRunTimes(timer.getRunTimes()+1);
			if(future.get().contains("\"result\":0")||future.get().contains("已完款")){
				System.out.println(DateUtils.dateToString(DateUtils.PATTEN_HMS)+"trade_no:"+timer.getTrade_no()+"第"+timer.getRunTimes()+"次通知成功");
				
				return;
			}else{
				System.out.println("++++++++++++++++future:"+future.get());
				logger.info("++++++++++++++++future:"+future.get());
				System.out.println(DateUtils.dateToString(DateUtils.PATTEN_HMS)+"trade_no:"+timer.getTrade_no()+"第"+timer.getRunTimes()+"次通知失败");
				
				submitWithDelay(task,10l);
			}
		} catch (Exception e) {
			
			System.out.println(DateUtils.dateToString(DateUtils.PATTEN_HMS)+"trade_no:"+timer.getTrade_no()+"第"+timer.getRunTimes()+"次通知出现错误");
			submitWithDelay(task,10l);
			return;
		}
    }
    //提交延时任务,成功接到返回值退出方法,失败继续提交任务
    public static void submitWithDelay(Callable<String> task,Long delay) {
    	NotifyMCTimer timer = (NotifyMCTimer)task;
    	if(timer.getRunTimes()>=5){
    		
    		System.out.println(DateUtils.dateToString(DateUtils.PATTEN_HMS)+"trade_no:"+timer.getTrade_no()+"通知达到5次最大次数");
    		return;
    	}else{
    		try {
	    		ScheduledFuture<String> future = scheduledExecutor.schedule(task, delay, TimeUnit.MINUTES);
	    		timer.setRunTimes(timer.getRunTimes()+1);
    			if(future.get().contains("\"result\":0")||future.get().contains("已完款")){
    				System.out.println(DateUtils.dateToString(DateUtils.PATTEN_HMS)+"trade_no:"+timer.getTrade_no()+"第"+timer.getRunTimes()+"次通知成功");
    				
    				return;
    			}else {
    				System.out.println("++++++++++++++++future:"+future.get());
    				logger.info("++++++++++++++++future:"+future.get());
    				System.out.println(DateUtils.dateToString(DateUtils.PATTEN_HMS)+"trade_no:"+timer.getTrade_no()+"第"+timer.getRunTimes()+"次通知失败");
    				
    				if(timer.getRunTimes()<5){
    					submitWithDelay(task,delay);
    				}
    			}
    		} catch (Exception e) {
    			
    			System.out.println(DateUtils.dateToString(DateUtils.PATTEN_HMS)+"trade_no:"+timer.getTrade_no()+"第"+timer.getRunTimes()+"次通知出现错误");
    			submitWithDelay(task,delay);
    			return;
    		}
    	}
	}
    //工具类入口方法,将定时任务放入队列
	public static void addToQueue(Callable<String> task) throws InterruptedException{
		startUp();
		queue.put(task);
	}
    //保存任务的队列
    static class MyBlockingQueue<E> {
		private Queue<E> queue = null;
		private int limit;
		private Lock lock = new ReentrantLock();
		private Condition notFull  = lock.newCondition(); 
		private Condition notEmpty = lock.newCondition(); 


		public MyBlockingQueue(int limit) {
			this.limit = limit;
			queue = new ArrayDeque<>(limit);
		}
        
		public void put(E e) throws InterruptedException {
			lock.lockInterruptibly();
			try{
				while (queue.size() == limit) {
					notFull.await();
				}
				queue.add(e);
				notEmpty.signal();	
			}finally{
				lock.unlock();
			}
			
		}

		public E take() throws InterruptedException {
			lock.lockInterruptibly();
			try{
				while (queue.isEmpty()) {
					notEmpty.await();
				}
				E e = queue.poll();
				notFull.signal();
				return e;	
			}finally{
				lock.unlock();
			}
		}
	}
    //消费者
	static class Consumer extends Thread {
		MyBlockingQueue<Callable<String>> queue;

		public Consumer(MyBlockingQueue<Callable<String>> queue2) {
			this.queue = queue2;
		}

		@Override
		public void run() {
			try {
				while (true) {
					Callable<String> task = queue.take();
					submitNoDelay(task);
				}
			} catch (InterruptedException e) {
			}
		}
	}
}

调用时直接放到任务队列:

ScheduledExecutorServiceUtil.addToQueue(new NotifyMCTimer(resultMap,paymentRecd.getNotifyUrl(),paymentRecd.getTradeNo()));

方法可能有缺陷,仅供参考

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ScheduledExecutorServiceJava中用来执行定时任务的线程池。它是Executor框架的一种实现,可以在指定的延迟之后或者按固定的时间间隔周期性地执行任务。 使用ScheduledExecutorService可以方便地创建一个线程池,其中的线程会自动调度执行任务,而不需要手动创建和管理线程。ScheduledExecutorService中的线程池可以根据需要动态地调整线程的数量,提供了更好的灵活性和效率。 使用ScheduledExecutorService来创建一个线程池可以通过Executors类的静态方法newScheduledThreadPool()来实现,例如: ```java ScheduledExecutorService executor = Executors.newScheduledThreadPool(5); ``` 上述代码创建了一个包含5个线程的ScheduledExecutorService线程池。 然后,可以使用ScheduledExecutorServiceschedule()方法来安排任务的执行。schedule()方法有多个重载形式,其中最常用的形式接受一个Runnable对象和一个延迟时间作为参数,例如: ```java executor.schedule(new RunnableTask(), 5, TimeUnit.SECONDS); ``` 上述代码将会在5秒之后执行RunnableTask任务。 除了schedule()方法外,还有scheduleAtFixedRate()和scheduleWithFixedDelay()方法可以用来周期性地执行任务。scheduleAtFixedRate()方法可以在固定的时间间隔内周期性地执行任务,而scheduleWithFixedDelay()方法则是在任务执行完成后在固定的延迟时间后再次执行任务。 总结起来,ScheduledExecutorService线程池提供了一种方便的方式来执行定时任务,可以根据需要动态调整线程数量,更加灵活和高效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值