java技术栈·定时任务解决方案

背景

在java的场景中,往往会遇到定时执行一些任务的场景,我把解决方案分为基于spring技术栈的和原生java技术栈的,定时执行任务很容易实现,但是过程中,需要踩很多坑,比如定时任务阻塞,定时任务执行报异常,定时任务超时等等的运行时情况,需要让定时任务很好的兼容,不能宕机。

解决方案

定时任务,当需要跟外部资源交互的时候,比如发送socket请求,发送rpc请求,获得数据库链接等等的需要与外部资源交互的时候,一旦触发异常或者是超时,需要有处理策略,保证定时任务,正常运行才可以,不能因为出现异常就崩了,阻塞了,不执行了。

JAVA自身定时任务方案

实现起来,需要考虑两步,定时任务的执行机制 + 执行过程中的保障机制。 这里举一个超时的例子,保证出现超时异常,其他异常的时候,代码会照样执行,如果没有保障机制,线程就会阻塞,一旦阻塞,就不会二次执行了,定时的功能就失去了。

 	Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(new Runnable() {
			public void run() {
				final ExecutorService exec = Executors.newFixedThreadPool(1);
				Callable<String> call = new Callable<String>() {
					public String call() throws Exception {
						//开始执行耗时操作  把那个run方法的功能放进来
						Thread.sleep(1000 * 5);
						throw  new TimeoutException();
						//return "线程执行完成.";
					}
				};
				try {
					Future<String> future = exec.submit(call);
					String obj = future.get(1000 * 4, TimeUnit.MILLISECONDS); //任务处理超时时间设为 4 秒
					System.out.println("任务成功返回:" + obj);
				} catch (TimeoutException ex) {
					System.out.println("处理超时啦....");
					ex.printStackTrace();
				} catch (Exception e) {
					System.out.println("处理失败.");
					e.printStackTrace();
				}finally {
					// 关闭线程池
					exec.shutdown();
				}

			}
		}, 0, 4, TimeUnit.SECONDS);


		// 阻塞线程,模拟主程序一直运行
		try {
			Thread.sleep(1000000000);
		}catch (Exception e){

		}

spring方案

spring封装的比较好了,只增加定时任务的执行保障机制就可以了。建议加异步标签,防止影响主线程。调用的方法内部自己根据业务加保障机制,比如超时,异常捕捉,等等

	/**
	 *定时清除frame
	 */
	@Async
	@Scheduled(initialDelay = 5*1000,fixedRate = 3000)
	public void autoClearFrame() {
		frameCache.autoClear();
	}

你可能感兴趣的:(java并发,多线程相关,java技术栈,java,开发语言,后端)