-
2017-02-07 19:14:04
1、在有响应的时候,使用ResponseFuture对象,并在onResponse方法中,将响应设置到Futrue中。
import com.google.common.util.concurrent.AbstractFuture;
public class ResponseFuture<JsonProtocol> extends AbstractFuture<JsonProtocol>
{
private final Executor executor;
public ResponseFuture()
{
if (ThreadLocalUtil.get("isServer") == null)
{
//TODO 这里是错误的,把这行代码移到一个单例的全局共享中取,避免每次new。如果是服务端,那么所有的服务端都共享一个线程池
executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(),
new RpcThreadFacotry("CallBack"));
}
else
{
//单线程执行器
executor = MoreExecutors.directExecutor();
}
}
/**
* 当响应回来的时候,结果被设置到future中,因此从future中可以获得一个异步的响应结果
* @param responseProtocol
*/
public void onResponse(JsonProtocol responseProtocol)
{
//向future中设置值
super.set(responseProtocol);
}
/**
* 当响应有结果时候可以直接runnable的方法
* @param runnable
*/
public void addCallBack(Runnable runnable)
{
super.addListener(runnable, executor);
}
}
2、等待线程获得响应结果(使用future.get阻塞等待异步线程的响应)
ResponseFuture<JsonProtocol> reponseFuture = client.futureInvoke(JsonProtocolReqeust);
JsonProtocol JsonProtocolResponse = null;
try
{
JsonProtocolResponse = reponseFuture.get(JsonProtocolReqeust.getRpcMetadata().getTimeOut(),
TimeUnit.MILLISECONDS);
}
catch (ExecutionException e){}
catch (TimeoutException e)
{
throw new RuntimeException("调用远程服务响应超时", e);
}
更多相关内容 -
多线程异步调用(并参递参数)
2012-01-12 10:02:59多线程异步调用(并参递参数)经典代码示例 -
Python多线程异步调用
2021-01-28 16:09:29本博客主要实现一个python多线程异步调用的demo。 程序功能简介:调用main_func作为主程序,主程序内部创建两个线程,分别建立线程ID、线程名和线程内部执行延迟时间,两个线程内部分别调用函数print_time...本博客主要实现一个python多线程异步调用的demo。
程序功能简介:调用main_func
作为主程序,主程序内部创建两个线程,分别建立线程ID、线程名和线程内部执行延迟时间,两个线程内部分别调用函数print_time
打印时间。exitFlag
作为标志位,如果为1表示线程不打印时间直接退出。
结果分析:程序主线程已经执行结束,并不影响其建立的线程执行,所以可以实现异步调用。程序代码:
import threading import time exitFlag = 0 class myThread (threading.Thread): def __init__(self, threadID, name, delay): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.delay = delay def run(self): print ("开始线程:" + self.name) print_time(self.name, self.delay, 3) print ("退出线程:" + self.name) def print_time(threadName, delay, times): for i in range(times): if exitFlag: threadName.exit() time.sleep(delay) print ("%s: %s" % (threadName, time.ctime(time.time()))) def main_func(): # 创建新线程 thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # 开启新线程 thread1.start() thread2.start() return '主程序执行结束!' if __name__ == "__main__": result = main_func() print(result)
执行结果
-
Java多线程实现异步调用的方法
2020-09-03 07:27:34本文给大家分享java多线程实现异步调用的方法,感兴趣的朋友跟着脚本之家小编一起学习吧 -
Labview2015多线程异步调用工程
2016-09-27 21:41:51labview2015关于异步调用功能的研究工程,主要用于解决主线程负责快速轮询,多个子线程负责具体的任务处理并反馈给主线程(子线程需要长时间处理任务),解决单纯的可重复VI不能实现并行的功能。 -
Labview异步调用示例
2019-03-31 20:58:53异步调用示例,Labview异步调用示例 -
【Java多线程】多线程实现异步调用结果返回
2020-05-18 20:01:15因此可以使用异步调用的方法,不阻塞当前其他任务的执行。 小栗子 首先我们先要创建一个线程池,可以根据自己的需求创建,什么IO密集型参数设置,CPU密集型参数的设置。这里我们仅仅想让10个任务一起跑。 ...前言
在我们的业务中很可能会碰到需要执行一段时间的任务,并且如果同步的话就会造成一些无谓的等待。因此可以使用异步调用的方法,不阻塞当前其他任务的执行。
小栗子
首先我们先要创建一个线程池,可以根据自己的需求创建,什么IO密集型参数设置,CPU密集型参数的设置。这里我们仅仅想让10个任务一起跑。
ExecutorService threadPool = new ThreadPoolExecutor( 10, 10, 0, TimeUnit.SECONDS, new SynchronousQueue<>(), new ThreadPoolExecutor.AbortPolicy());
然后模拟下需要异步调用的业务的执行,这里我的n给不同线程设置了不同的执行时间,在判断超时时,会有部分线程无法完成任务。AtomicInteger atomicInteger = new AtomicInteger(5); List<Future<Integer>> futures = new ArrayList<>(); //存储结果 for (int i = 0; i < 10; i++) { Future<Integer> submit = completionService.submit(() -> { int n = atomicInteger.getAndIncrement(); int h = 0; for (int j = n * 10; j < n * 10 + n; j++) { h += j; TimeUnit.SECONDS.sleep(1); //暂停线程1s } return h; }); futures.add(submit); }
现在执行下其他的业务操作。
然后设置一些调用其他接口超时的时间,避免过长等待并开始获取下调用的结果。
Set<AjaxResult> flags = new HashSet<>(); List<AjaxResult> FAILS =new LinkedList<>(); long startTime = System.currentTimeMillis(); long timeout = 1000 * 10; while (flags.size()+FAILS.size()<futures.size()) { for (Future<Integer> o : futures) { if (System.currentTimeMillis() - startTime > timeout ){// 如果超时采取一定措施,或者返回一个失败。 FAILS.add(new AjaxResult("fail",0)); if(flags.size()+FAILS.size()>=futures.size()){ break; } continue; } if (o.isDone()) { flags.add(new AjaxResult("success", o.get())); } } } long endTime = System.currentTimeMillis();
这里将结果分失败和成功进行存储。并记录处理的时间
接下来看下最后输出结果
System.out.println("执行结束"); System.out.println("耗时" + (endTime - startTime)); System.out.println("结果" + flags.toString()); System.out.println("失败" + FAILS.toString()); System.exit(0);
本方法纯属瞎玩,仅供参考。下面是全部的代码
public class InitConfig { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService threadPool = new ThreadPoolExecutor( 10, 10, 0, TimeUnit.SECONDS, new SynchronousQueue<>(), new ThreadPoolExecutor.AbortPolicy()); CompletionService<Integer> completionService = new ExecutorCompletionService<>(threadPool); AtomicInteger atomicInteger = new AtomicInteger(5); List<Future<Integer>> futures = new ArrayList<>(); for (int i = 0; i < 10; i++) { Future<Integer> submit = completionService.submit(() -> { int n = atomicInteger.getAndIncrement(); int h = 0; for (int j = n * 10; j < n * 10 + n; j++) { h += j; TimeUnit.SECONDS.sleep(1); //暂停线程1s } return h; }); futures.add(submit); } Set<AjaxResult> flags = new HashSet<>(); List<AjaxResult> FAILS =new LinkedList<>(); long startTime = System.currentTimeMillis(); long timeout = 1000 * 10; while (flags.size()+FAILS.size()<futures.size()) { for (Future<Integer> o : futures) { if (System.currentTimeMillis() - startTime > timeout ){ FAILS.add(new AjaxResult("fail",0)); if(flags.size()+FAILS.size()>=futures.size()){ break; } continue; } if (o.isDone()) { flags.add(new AjaxResult("success", o.get())); } } } long endTime = System.currentTimeMillis(); System.out.println("执行结束"); System.out.println("耗时" + (endTime - startTime)); System.out.println("结果" + flags.toString()); System.out.println("失败" + FAILS.toString()); System.exit(0); } @Data @AllArgsConstructor @NoArgsConstructor @ToString @EqualsAndHashCode static class AjaxResult { private String ret; private Integer data; } }
-
Java创建多线程异步执行实现代码解析
2020-08-18 17:48:08主要介绍了Java创建多线程异步执行实现代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
springboot项目中多线程应用,异步处理,异步调用
2022-04-11 23:21:30springboot项目中多线程应用,异步处理,异步调用 多线程的应用 线程池的应用 异步处理 异步调用 随着开发经验的积累,我们逐渐都了解到了项目中需要多线程的应用或者线程池的应用,有一些耗时的业务需要我们去进行...springboot项目中多线程应用,异步处理,异步调用
多线程的应用
线程池的应用
异步处理
异步调用
随着开发经验的积累,我们逐渐都了解到了项目中需要多线程的应用或者线程池的应用,有一些耗时的业务需要我们去进行异步调用,特别是针对于一些其他部门所提供的接口,因此码下这篇博客,希望对大家有用!
配置一个线程池
@EnableAsync @Configuration @Slf4j public class ThreadPoolConfig { @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } // 当池子大小小于corePoolSize,就新建线程,并处理请求 // 当池子大小等于corePoolSize,把请求放入workQueue(QueueCapacity)中,池子里的空闲线程就去workQueue中取任务并处理 // 当workQueue放不下任务时,就新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize,就用RejectedExecutionHandler来做拒绝处理 // 当池子的线程数大于corePoolSize时,多余的线程会等待keepAliveTime长时间,如果无请求可处理就自行销毁 @Bean(name = "asyncServiceExecutor") public Executor asyncServiceExecutor() { log.info("start asyncServiceExecutor"); ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(10); executor.setKeepAliveSeconds(30); executor.setThreadNamePrefix("async-"); // rejection-policy:当pool已经达到max size的时候,如何处理新任务 // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } }
定义两个额外的比较耗时的测试接口
@Slf4j @RestController @RequestMapping(value = "/test") public class TestController { @GetMapping(value = "/hello1") public JSONObject hello1 (String name) throws InterruptedException { log.info("this is hello1 ---> sleep(5000) begin " + new Date()); Thread.sleep(5000); log.info("this is hello1 ---> sleep(5000) end " + new Date()); JSONObject res = new JSONObject(); res.put("name", "hello1-" + name); return res; } @GetMapping(value = "/hello2") public JSONObject hello2 (String name) throws InterruptedException { log.info("this is hello2 ---> sleep(8000) begin " + new Date()); Thread.sleep(8000); log.info("this is hello2 ---> sleep(8000) end " + new Date()); JSONObject res = new JSONObject(); res.put("name", "hello2-" + name); return res; } }
定义多线程调用的业务类
@Service @Slf4j public class OtherService { @Autowired private RestTemplate restTemplate; @Async("asyncServiceExecutor") public CompletableFuture<JSONObject> invokeHello1(String name){ String url = "http://localhost:8080/test/hello1?name=" + name; log.info("多线程开始执行{}, threadId:{}, threadName:{}", url, Thread.currentThread().getId(), Thread.currentThread().getName()); ResponseEntity<JSONObject> responseEntity = restTemplate.getForEntity(url, JSONObject.class); JSONObject jsonRes = responseEntity.getBody(); log.info("多线程执行完毕{}, 响应Res:{}, threadId:{}, threadName:{}", url, jsonRes, Thread.currentThread().getId(), Thread.currentThread().getName()); return CompletableFuture.completedFuture(jsonRes); } @Async("asyncServiceExecutor") public CompletableFuture<JSONObject> invokeHello2(String name){ String url = "http://localhost:8080/test/hello2?name=" + name; log.info("多线程开始执行{}, threadId:{}, threadName:{}", url, Thread.currentThread().getId(), Thread.currentThread().getName()); ResponseEntity<JSONObject> responseEntity = restTemplate.getForEntity(url, JSONObject.class); JSONObject jsonRes = responseEntity.getBody(); log.info("多线程执行完毕{}, 响应Res:{}, threadId:{}, threadName:{}", url, jsonRes, Thread.currentThread().getId(), Thread.currentThread().getName()); return CompletableFuture.completedFuture(jsonRes); } }
定义要使用多线程的接口
@Slf4j @RestController @RequestMapping(value = "/test") public class TestController { @Autowired private Demo3Service demo3Service; @GetMapping(value = "/testHello") public JSONObject testHello (String name) throws ExecutionException, InterruptedException { return demo3Service.testHello(name); } }
定义要使用多线程的servcie
@Service @Slf4j public class Demo3Service { @Autowired private OtherService otherService; public JSONObject testHello (String name) throws ExecutionException, InterruptedException { log.info("this is demo3Service.testHello({}), begin -> {}", name, new Date()); // 此处hello1和hello2均为异步调用 CompletableFuture<JSONObject> hello1Future = otherService.invokeHello1(name); CompletableFuture<JSONObject> hello2Future = otherService.invokeHello2(name); // 这里可以处理其他的业务逻辑 log.info("async invoke doing..."); // 开始处理hello1和hello2的接口相应 CompletableFuture.allOf(hello1Future, hello2Future).join(); JSONObject hello1Res = hello1Future.get(); JSONObject hello2Res = hello2Future.get(); log.info("this is demo3Service.testHello({}), end -> {}", name, new Date()); JSONObject jsonRes = new JSONObject(); jsonRes.put("hello1", hello1Res.get("name")); jsonRes.put("hello2", hello2Res.get("name")); return jsonRes; } }
最后,让我们一起来测试一下 http://localhost:8080/test/testHello?name=zhangsan这个接口
一起来看一下控制台输出的日志
this is demo3Service.testHello(zhangsan), begin -> Mon Apr 11 22:59:13 CST 2022 async invoke doing... 多线程开始执行http://localhost:8080/test/hello1?name=zhangsan, threadId:43, threadName:async-1 多线程开始执行http://localhost:8080/test/hello2?name=zhangsan, threadId:44, threadName:async-2 this is hello2 ---> sleep(8000) begin Mon Apr 11 22:59:13 CST 2022 this is hello1 ---> sleep(5000) begin Mon Apr 11 22:59:13 CST 2022 this is hello1 ---> sleep(5000) end Mon Apr 11 22:59:18 CST 2022 多线程执行完毕http://localhost:8080/test/hello1?name=zhangsan, 响应Res:{"name":"hello1-zhangsan"}, threadId:43, threadName:async-1 this is hello2 ---> sleep(8000) end Mon Apr 11 22:59:21 CST 2022 多线程执行完毕http://localhost:8080/test/hello2?name=zhangsan, 响应Res:{"name":"hello2-zhangsan"}, threadId:44, threadName:async-2 this is demo3Service.testHello(zhangsan), end -> Mon Apr 11 22:59:21 CST 2022
OK,这就是多线程/线程池的一个基本使用了,希望能帮到大家
-
Java多线程实现异步调用实例
2014-09-18 15:09:21Java多线程实现异步调用实例。运行Main可以看到结果。main是主线程,另有A,B,C三个线程用不同的时间跑完。 -
java线程异步调用
2018-11-07 09:54:13本文主要讲解生产环境中遇到的异步加载数据问题以及相应的解决思路。 系统登录的时候,需要根据用户ID生成一些和当前...在Java程序中,如果想实现异步调用方法的功能,需要通过线程方式实现,即实现java.lang.Ru... -
Java多线程编程-(17)-多线程异步调用之Future模式
2017-10-30 10:27:27一、线程计数器回顾在《Java多线程编程-(6)-两种常用的线程计数器CountDownLatch和循环屏障CyclicBarrier》 这一篇中,我们使用线程计数器的方式实现了在主线程中等待计数的线程执行完之后在执行阻塞等待之后的... -
SpringBoot使用多线程实现异步调用
2018-03-22 21:40:06一、在想要异步执行的方法上加上@Async注解二、在主函数运行类上开启异步注解@EnableAsync -
三分钟熟悉@Async注解------Spring多线程异步调用的艺术
2020-04-03 10:22:45同步调用 我们写的Java代码,大多数都是同步调用,只启动一个线程。所谓同步调用,举个简单的例子: 某个程序一开始执行方法A(); 当执行到某处,需要调用另一个方法B()... 当我们想多线程执行程序,即执行A()的... -
多线程异步调用接口数据同步问题
2019-08-27 18:16:00在多线程进行接口调用时如果调用的接口执行时间不同会直接跳过慢的接口,导致最终数据出错。 PrintUtil类模拟被调用的2个接口方法 ThreadDemo类是多线程的实现类 Test类是调用方。 注释掉f1.join()时执行结果:... -
C#多线程与异步的区别详解
2020-12-31 09:36:31多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至有些时候我们就认为多线程和异步操作是等同的概念。但是,多线程和异步操作还是有一些区别的。而这些区别造成了使用多线程和... -
java多线程异步和阻塞性调用方式
2018-04-26 11:39:10java多线程可以直接通过ExecutorService接口的execute方法提交任务,也可以通过invokeAll方法让多个任务一起提交,前者execute是异步提交,也就是说不会阻塞主线程,后则会阻塞主线程,等待所有任务执行完成主线程才... -
今天在spring-cloud项目中,使用多线程异步调用微服务出现的错误
2020-04-23 19:28:43使用背景:今天在spring-cloud项目中,使用多线程异步调用微服务出现的错误 Nothread-boundrequestfound:Areyoureferringtorequestattributesoutsideofanactualwebrequest,... -
Java接口异步调用
2020-08-26 00:11:43主要介绍了Java接口异步调用,下面我们来一起学习一下吧 -
异步调用与多线程的区别
2015-10-09 15:47:10异步调用与多线程的区别 -
多线程异步调用的问题
2013-11-19 13:33:26请改造以下类,使之在多线程异步调用时,而不会出数据覆盖,即并发冲突 pulbi class Math { private static int result = 0; public static int sum(int a, int b){ result = a + b; return result; } ... -
java多线程之异步使用
2021-02-25 20:01:50在编程中,根据实际场景,我们有时会考虑使用异步执行来提高应用的响应速度;一个简单的例子:@Testpublic void futureTest() {// 注意使用 ExecutorService 而非 ExecutorExecutorService executorService = Executors.... -
说说Java异步调用的几种方式
2022-03-17 15:59:09目录 一、通过创建新线程 二、通过线程池 三、通过@Async注解 ...首先的我们得认识到,异步调用的本质,其实是通过开启一个新的线程来执行。如以下例子: public static void main(String[] args) . -
异步调用的参数及返回值
2011-10-25 10:48:27异步调用的参数及返回值的处理 异步调用的参数及返回值的处理 -
C#多线程和异步
2018-04-25 22:12:43一、使用计时器在某些情况下,可能不需要使用单独的线程。如果应用程序需要定期执行简单的与 UI 有关的操作,则应该考虑使用进程计时器。有时,在智能客户端应用程序中使用进程计时器,以达到下列目:• 按计划定期... -
详解异步多线程使用中的常见问题
2021-11-08 14:55:20上一篇:异步多线程之Parallel 异常处理 小伙伴有没有想过,多线程的异常怎么处理,同步方法内的异常处理,想必都非常非常熟悉了。那多线程是什么样的呢,接着我讲解多线程的异常处理 首先,我们定义个任务列表,当... -
Java多线程之定时任务 以及 SpringBoot多线程实现定时任务——异步任务
2022-03-12 17:59:541. SpringBoot 自定义线程池以及多线程间的异步调用(@Async、@EnableAsync) 2.Java多线程之定时任务 以及 SpringBoot多线程实现定时任务 3.@EnableScheduling 与 @Scheduled