异步处理FutureTask实例「建议收藏」

异步处理FutureTask实例「建议收藏」   在Web应用前端,AJAX有同步和异步处理,异步可以避免阻塞。在WEB后端一般业务应用大多为同步处理,但也有一些需要异步处理的场合,比如A系统调B系统接口I,但B系统处理时间很长,这时,A系统主线程不能一直阻塞等待,可以使用异步处理。即先调用接口I,随即做后面的处理,等B系统返回值时再进行返回后处理。时序为:A:invokeIA:dootherthingB:处理完成,…

大家好,又见面了,我是你们的朋友全栈君。

    在Web应用前端,AJAX有同步和异步处理,异步可以避免阻塞。在WEB后端一般业务应用大多为同步处理,但也有一些需要异步处理的场合,比如A系统调B系统接口I,但B系统处理时间很长,这时,A系统主线程不能一直阻塞等待,可以使用异步处理。即先调用接口I,随即做后面的处理,等B系统返回值时再进行返回后处理。

时序为:

A: invoke I

A:do otherthing

B:处理完成,返回值

A:根据接口返回值进行后处理

1、代码例子:

package com.hf.test;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

import com.xxx.framework.po.ResponseResult;

public class FutureTest {
	Map<String, Object> params = new HashMap<String,Object>(); 
	
	ExecutorService executorService = Executors.newFixedThreadPool(3);
	
	public void test1(){
		params.put("clsId","clsId-001");
		params.put("ids", "001,002,003,004");
		FutureTask<ResponseResult> futureTask = new FutureTask<>(
				new MyTask(params));  
		

		executorService.submit(futureTask); 
		executorService.submit(new MonitorTask(futureTask));
		executorService.submit(getCollectJob(futureTask));
		
		System.out.println("HERE!!!");
	} 
	
	
	/**
	 * 返回收集工作
	 * @param futureTask
	 * @return
	 */
	public Runnable getCollectJob(final FutureTask<ResponseResult> futureTask) {
		return new Runnable() {
			public void run() {
				while(true){
					try {
						Thread.sleep(100); 
						if(futureTask.isDone()){
							ResponseResult resp = futureTask.get();
							System.out.println("2返回值:" + resp.getData());
							break;
						}		
						System.out.println("2Not finished.");
					} catch (Exception e) {
						e.printStackTrace();
					} 
				} 
			}
		};
	}
	
	
	/**
	 * 关闭线程池
	 */
	public void closeThreadPool(){
		executorService.shutdown();
	}  
	
	
	/**
	 * 测试主入口
	 * @param args
	 */
	public static void main(String[] args) {
		FutureTest ft = new FutureTest();
		ft.test1();
 
		System.out.println("Do other things...");
		ft.closeThreadPool();
	}
}

程序说明:

    这里采用的模式是调用接口和收集结果2条线,分别用不同的线程来执行。调用接口线程sumit后,收集线程随即开始工作,每隔100ms查询一遍返回状态,若接口返回,则打印返回值,否则一直打印“NOT  FINISHED”。

2、例子2

    若需要处理复杂的情形,如使用回调、传入参数处理返回结果,则可参考下面的例子。

package com.hf.test;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

import com.xxx.framework.po.ResponseResult;

public class FutureTest2 {
	Map<String, Object> initParams = new HashMap<String,Object>(); 
	
	ExecutorService executorService = Executors.newFixedThreadPool(3);
	
	public void test1(){
		initParams.put("clsId","clsId-001");
		initParams.put("ids", "001,002,003,004"); 
		
		MyCallback myCallback = new MyCallback(initParams);
		FutureTask<ResponseResult> futureTask = new FutureTask<>(
				new MyTask2(myCallback));  		

		executorService.submit(futureTask);  
		
		System.out.println("HERE!!!");
	}  
	
	
	/**
	 * 关闭线程池
	 */
	public void closeThreadPool(){
		executorService.shutdown();
	}  
	
	
	/**
	 * 测试主入口
	 * @param args
	 */
	public static void main(String[] args) {
		FutureTest2 ft = new FutureTest2();
		ft.test1();
 
		System.out.println("Do other things...");
		ft.closeThreadPool();
	}
}

回调处理类:

package com.hf.test;

import java.util.HashMap;
import java.util.Map;

import com.xxx.framework.po.ResponseResult;

public class MyCallback {
	Map<String, Object> initParams = new HashMap<String, Object>();
	
	public MyCallback(Map<String, Object> initParams){
		this.initParams = initParams;
	} 
	
	public ResponseResult doSomething(Map<String,Object> params){
		System.out.println("HERE:" + params);
		String result = "Found param pwid:" + params.get("pwid") 
			+ ",state:" + params.get("state");
		System.out.println("异步线程处理完成,结果:" + result);
		return ResponseResult.successResult("异步线程处理完成,结果:" + result);
	}
}

异步任务类:

package com.hf.test;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;

import com.xxx.framework.po.ResponseResult;
 
public class MyTask2 implements Callable<ResponseResult>{ 	
 
	MyCallback myCallback = null;
	
	public MyTask2(MyCallback myCallback){
		this.myCallback = myCallback;
	}  

	@Override
	public ResponseResult call() throws Exception {
		System.out.println("Start processing...");
		
		//模拟处理过程
		Thread.sleep(10*1000); 
		Map<String, Object> params = new HashMap<String,Object>(); 
		params.put("pwid","pwid-001");
		params.put("state", "已退回");
		//模拟处理结束
		ResponseResult result = myCallback.doSomething(params);
		return result;
	}
}

程序说明:

    主线程类为FutureTest2,异步任务类为MyTask2,回调类为MyCallback。将回调处理类作为参数传给异步任务类myTask2,当任务结束时,调用回调处理类MyCallback的回调函数,完成任务结束后的“后处理”。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/149955.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月17日 下午1:16
下一篇 2022年6月17日 下午1:36


相关推荐

  • 选择合适的innodb_log_file_size

    选择合适的innodb_log_file_size

    2021年9月4日
    64
  • 一维条形码检测与识别原理是什么_一维条码的识别原理

    一维条形码检测与识别原理是什么_一维条码的识别原理近期在学习的内容之中的一个,整理一下,图片均为网络图片。提及的条形码主要为EAN-13码。一、概念条形码由宽度不同、反射率不同的条(黑色)和空(白色)组成。依照特定的编码规则编制,用来表达一组数字

    2022年8月4日
    9
  • 三本毕业北京打工考研北大计算机,知乎刘洋:三本到北大软微到牛津博士,最后在哈工深当老师。…

    三本毕业北京打工考研北大计算机,知乎刘洋:三本到北大软微到牛津博士,最后在哈工深当老师。…(转发侵删)背景:当年在某三本独立学院,考研一志愿报了北大信科,没过复试线,校内调剂至北大软件工程参加复试复试时第一个问题是让简单介绍一下自己和本科学校,我刚说到学校名字就被考官打断了:“你的本科学校叫AA大学BB学院,那它到底是AA大学的一个下属学院呢,还是个跟AA大学没啥关系的独立学院呢?”我回答说:“是个独立学院,三本。”于是全场寂静,空气凝结。当时的直觉就是,这伙哥们儿肯定在想:“你一个…

    2026年2月11日
    5
  • 用Python分析2000款避孕套,得出这些有趣的结论

    用Python分析2000款避孕套,得出这些有趣的结论到现在为止,我们的淘宝教程已经写到了第四篇,前三篇分别是:第一篇:Python模拟登录淘宝,详细讲解如何使用requests库登录淘宝pc端。第二篇:淘宝自动登录2.0,新增Cookies序列化,教大家如何将cookies保存起来。第三篇:Python爬取淘宝商品避孕套,教大家如何爬取淘宝pc端商品信息。今天,我们来看看淘宝系列的第四篇我们在上一篇的时候已经将淘宝数据爬取下来了,…

    2022年5月25日
    53
  • dex文件介绍

    dex文件介绍搭建环境Ubuntu18.04.1LTSandroid-ndk-r17-beta2FFmpeg4.0.2编译FFmpeg修改configure配置编译脚本报错调整错误1:错误2:错误3:错误4:错误5:搭建环境Ubuntu18.04.1LTS需要安装yasm:sudoapt-getinstallyasmand…

    2022年6月27日
    34
  • 如何编写单元测试用例

    如何编写单元测试用例 一、单元测试的概念  单元通俗的说就是指一个实现简单功能的函数。单元测试就是只用一组特定的输入(测试用例)测试函数是否功能正常,并且返回了正确的输出。  测试的覆盖种类  1.语句覆盖:语句覆盖就是设计若干个测试用例,运行被测试程序,使得每一条可执行语句至少执行一次。  2.判定覆盖(也叫分支覆盖):设计若干个测试用例,运行所测程序,使程序中每个判断的取真分支和取假分支至少执行一次。  3.条件…

    2022年6月16日
    50

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号