精华内容
下载资源
问答
  • 本文给大家分享java多线程实现异步调用的方法,感兴趣的朋友跟着脚本之家小编一起学习吧
  • Java多线程实现异步调用实例。运行Main可以看到结果。main是主线程,另有A,B,C三个线程用不同的时间跑完。
  • Java多线程实现异步调用

    千次阅读 2017-03-21 16:18:59
    原文地址:Java多线程实现异步调用作者:chuansir 在JAVA平台,实现异步调用的角色有如下三个角色:调用者 提货单 真实数据 一个调用者在调用耗时操作,不能立即返回数据时,先返回一个提货单.然后在过一断时间后凭...
    原文地址:Java多线程实现异步调用 作者:chuansir
    在JAVA平台,实现异步调用的角色有如下三个角色:调用者  提货单      真实数据
    一个调用者在调用耗时操作,不能立即返回数据时,先返回一个提货单.然后在过一断时间后凭提货单来获取真正的数据.
    去蛋糕店买蛋糕,不需要等蛋糕做出来(假设现做要很长时间),只需要领个提货单就可以了(去干别的事情),等到蛋糕做好了,再拿提货单取蛋糕就可以了。
    public class Main {   
    1.     public static void main(String[] args) {   
    2.         System.out.println("main BEGIN");   
    3.         Host host new Host();   
    4.         Data data1 host.request(10'A');   
    5.         Data data2 host.request(20'B');   
    6.         Data data3 host.request(30'C');   
    7.   
    8.         System.out.println("main otherJob BEGIN");   
    9.         try {   
    10.             Thread.sleep(200);   
    11.         catch (InterruptedException e) {   
    12.         }   
    13.         System.out.println("main otherJob END");   
    14.   
    15.         System.out.println("data1 " data1.getContent());   
    16.         System.out.println("data2 " data2.getContent());   
    17.         System.out.println("data3 " data3.getContent());   
    18.         System.out.println("main END");   
    19.     }   
    20.  
      这里的main类就相当于“顾客”,host就相当于“蛋糕店”,顾客向“蛋糕店”定蛋糕就相当于“发请求request”,返回的数据data是FutureData的实例,就相当于提货单,而不是真正的“蛋糕”。在过一段时间后(sleep一段时间后),调用data1.getContent(),也就是拿提货单获取执行结果。

    下面来看一下,顾客定蛋糕后,蛋糕店做了什么:

    1. public class Host   
    2.     public Data request(final int count, final char c) {   
    3.         System.out.println("request(" count ", " ") BEGIN");   
    4.   
    5.         // (1) 建立FutureData的实体   
    6.         final FutureData future new FutureData();   
    7.   
    8.         // (2) 为了建立RealData的实体,启动新的线程   
    9.         new Thread()                                         
    10.             public void run()   
    11.              //在匿名内部类中使用count、future、c。                        
    12.                 RealData realdata new RealData(count, c);   
    13.                 future.setRealData(realdata);   
    14.                                                              
    15.         }.start();                                             
    16.   
    17.         System.out.println("request(" count ", " ") END");   
    18.   
    19.         // (3) 取回FutureData实体,作为传回值   
    20.         return future;   
    21.     }   
    22.  
      host("蛋糕店")在接到请求后,先生成了“提货单”FutureData的实例future,然后命令“蛋糕师傅”RealData去做蛋糕,realdata相当于起个线程去做蛋糕了。然后 host返回给顾客的仅仅是“提货单”future,而不是蛋糕。当蛋糕做好后, 蛋糕师傅才能给对应的“提货单”蛋糕,也就是future.setRealData(realdata)。

      

    下面来看看蛋糕师傅是怎么做蛋糕的:

    建立一个字符串,包含count个c字符,为了表现出犯法需要花费一些时间,使用了sleep。

     public class RealData implements Data {   
    1.     private final String content;   
    2.     public RealData(int count, char c) {   
    3.         System.out.println("making RealData(" count ", " ") BEGIN");   
    4.         char[] buffer new char[count];   
    5.         for (int 0count; i++) {   
    6.             buffer[i] c;   
    7.             try {   
    8.                 Thread.sleep(1000);   
    9.             catch (InterruptedException e) {   
    10.             }   
    11.         }   
    12.         System.out.println("making RealData(" count ", " ") END");   
    13.         this.content new String(buffer);   
    14.     }   
    15.     public String getContent() {   
    16.         return content;   
    17.     }   
    18.  

         现在来看看“提货单”future是怎么与蛋糕"content"对应的:

     
    public class FutureData implements Data {   
    1.     private RealData realdata null;   
    2.     private boolean ready false;   
    3.   
    4.     public synchronized void setRealData(RealData realdata) {   
    5.         if (ready)                           
    6.             return    // 防止setRealData被调用两次以上。 
    7.         }   
    8.         this.realdata realdata;   
    9.         this.ready true;   
    10.         notifyAll();   
    11.     }   
    12.     public synchronized String getContent() {   
    13.         while (!ready) {   
    14.             try {   
    15.                 wait();   
    16.             catch (InterruptedException e) {   
    17.             }   
    18.         }   
    19.         return realdata.getContent();   
    20.     }   
    21.  

       顾客做完自己的事情后,会拿着自己的“提货单”来取蛋糕:

      

    System.out.println("data1 " data1.getContent());  

     

     这时候如果蛋糕没做好,就只好等了:

     
    while (!ready) {   
    1.             try {   
    2.                 wait();   
    3.             catch (InterruptedException e) {   
    4.             }   
    5. //等做好后才能取到     
    6. return realdata.getContent();  

        程序分析

     

        对于每个请求,host都会生成一个线程,这个线程负责生成顾客需要的“蛋糕”。在等待一段时间以后,如果蛋糕还没有做好,顾客还必须等待。直到“蛋糕被做好”,也就是

    future.setRealData(realdata); 执行以后,顾客才能拿走蛋糕。

       每个线程只是专门负责制作特定顾客所需要的“蛋糕”。也就是顾客A对应着蛋糕师傅A,顾客B对应着蛋糕师傅B。即使顾客B的蛋糕被先做好了,顾客A也只能等待蛋糕师傅A把蛋糕做好。换句话说,顾客之间没有竞争关系。

       类FutureData的两个方法被设置为synchronized,实际上蛋糕师傅A与顾客A之间的互斥关系,也就是顾客A必须等待蛋糕师傅A把蛋糕做好后,才能拿走,而与蛋糕师傅B是否做好了蛋糕没有关系。

    展开全文
  • 主要为大家详细介绍了Java多线程异步Future机制的原理和实现,感兴趣的小伙伴们可以参考一下
  • JAVA使用线程实现异步处理情景代码实现 情景 快餐店现场点餐,客户向服务员提交了订单,服务员收到订单后首先返回给用户一个取餐码,并同时将订单传给后厨,后续用户再根据取餐码取餐。 代码实现 public class ...

    JAVA使用线程实现异步处理

    情景

    快餐店现场点餐,客户向服务员提交了订单,服务员收到订单后首先返回给用户一个取餐码,并同时将订单传给后厨,后续用户再根据取餐码取餐。

    代码实现

    public class OrderShop {
        public ResponseEntity request(){
            new Thread(){
                @Override
                public void run(){
                    while (true){
                        System.out.println("正在制作");
                    }
                }
            }.start();
            String uuid = UUID.randomUUID().toString().replaceAll("-","");
            return ResponseEntity.getSuccessResponse("订单号:"+uuid);
        }
    }
    
    展开全文
  • 因此可以使用异步调用的方法,不阻塞当前其他任务的执行。 小栗子 首先我们先要创建一个线程池,可以根据自己的需求创建,什么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利用多线程实现异步调用

    千次阅读 2012-03-13 15:03:25
    java利用多线程实现异步调用 package com.test.t1; public class Test2 { public static void main(String[] args) { final FutureTicket ft = new FutureTicket(new MyProcessData()); // 在新线程中调用...
    java利用多线程实现异步调用
    
    
    package com.test.t1;
    
    public class Test2 {
    
    	public static void main(String[] args) {
    		final FutureTicket ft = new FutureTicket(new MyProcessData());
    
    		// 在新线程中调用耗时操作
    		new Thread() {
    			public void run() {
    				ft.makeRealData();
    			}
    		}.start();
    		ft.putData();
    	}
    }
    
    class FutureTicket {
    	private Object data = null;
    	private boolean completed = false;
    	private ProcessData pd;
    
    	public FutureTicket(ProcessData pd) {
    		this.pd = pd;
    	}
    
    	public synchronized void makeRealData() {
    		if (this.completed)
    			return;
    		// 获取数据的耗时操作.这里用Sleep代替
    		try {
    			Thread.sleep(10000);
    		} catch (Throwable t) {
    		}
    		this.data = "返回的数据内容";
    		this.completed = true;
    		notifyAll();
    	}
    
    	public synchronized void putData() {
    		while (!this.completed) {
    			try {
    				wait();
    			} catch (Throwable t) {
    			}
    		}
    		// return this.data;
    		// 不用返回了,直接处理
    		this.pd.process(this.data);
    		// alert(?);
    
    	}
    
    	// 这个方法也可以不要了.
    	public boolean isCompleted() {
    		return this.completed;
    	}
    }
    
    interface ProcessData {
    	public void process(Object data);
    }
    
    class MyProcessData implements ProcessData {
    	public void process(Object data) {
    		// 你不管什么时候起初数据data被获取了.
    		// 你只要规定如果获取到数据了如何处理
    
    		System.out.println(data.toString() + "处理完成...........");
    		// insert into dataBase?
    	}
    }

    展开全文
  • 主要介绍了Java创建多线程异步执行实现代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • JAVA多线程Future异步返回实现

    千次阅读 2019-01-13 21:41:11
    Future基本知识不做介绍,主要是简单的实现方式 1.创建线程池 FixedThreadPool 与 CachedThreadPool 特性对比 特性 FixedThreadPool CachedThreadPool 重用 FixedThreadPool 与 CacheThreadPool差不多...
  • java多线程异步

    千次阅读 2019-05-17 17:49:29
    考虑一定得用多线程处理,那就首先需要线程池了,毕竟没有线程池的情况下很容易出现无休止创建线程是非常危险的。 实现 代码 伪代码 //创建线程池 ExecutorService executor = Executors.newFixedThreadPool(4)...
  • Java多线程技术实现异步调用机制

    千次阅读 2018-06-01 22:14:29
    首先定义一个接口:Icallback:代码如下 :public interface ...}定义该接口的实现类:MyCallbackpublic class MyCallback implements Icallback { @Override public void call() { System.out.println(Thread.curren...
  • java多线程异步实例

    2012-11-19 11:17:28
    java线程异步案例,以三个线程作为案例典型,同时发起三个线程,根据不同的订单领取各自的物品,自作过程同步处理。
  • java多线程异步

    2009-05-10 12:38:35
    这是用java做的,体现多线程中的异步性的一个小程序。对初学者挺实用的...
  • Java线程实现异步消息

    千次阅读 2010-10-07 23:00:00
    import java.util.concurrent.TimeUnit;class MyObject implements Runnable { private Monitor monitor; public MyObject(Monitor monitor) { this.monitor = monitor; } public void run() { try { ...
  • SpringBoot使用多线程实现异步调用

    千次阅读 2018-03-22 21:40:06
    一、在想要异步执行的方法上加上@Async注解二、在主函数运行类上开启异步注解@EnableAsync
  • Java 多线程同步和异步详解

    千次阅读 2018-05-31 10:00:32
    转载自 https://www.cnblogs.com/mengyuxin/p/5358364.htmljava线程 同步与异步 线程池1)多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线程的处理的数据,而B线程又修改了...
  • 如何用Java回调和线程实现异步调用

    千次阅读 2015-08-25 22:18:51
    如何用Java回调和线程实现异步调用软件模块之间的调用关系可以分为两大类:即同步调用和异步调用。在同步调用中,一段代码(主调方)调用另一段代码(被调方),主调方必须等待这段代码执行完成返回结果后,才能继续...
  • Java多线程异步处理

    千次阅读 2020-04-21 14:34:00
    1.异步执行无返回值 CompletableFuture noArgsFuture = CompletableFuture.runAsync(new Runnable() { @Override public void run() { System.out.println("***************"); ...
  • JAVA多线程以及Spring异步注解@Async

    千次阅读 2020-05-30 22:26:27
    文章目录JAVA多线程以及Spring异步注解@Async关于多线程关于线程池如何创建线程池早期创建线程池的方式规范地使用线程池spring线程池配置@Async注解作用域引入依赖启动Spring异步注解无需返回的异步调用带Future返回...
  • Java多线程同步和异步详解

    千次阅读 2016-11-12 22:26:50
    1. 多线程并发时,多个线程同时请求同一资源,必然导致此资源的数据不安全。 2. 线程池 在WEB服务中,对于web服务器的响应速度必须尽可能的快,这就容不得在用户提交请求按钮后,再创建线程提供服务。为了减少用户...
  • Future是Java 5添加的类,用来描述一个异步计算的结果,但是获取一个结果时方法较少,要么通过轮询isDone,确认完成后,调用get()获取值,要么调用get()设置一个超时时间。但是这个get()方法会阻塞住调用线程,这种...
  • Java多线程实现下载功能

    万次阅读 2012-11-22 11:38:19
    Java多线程的好处挺多的,可以充分利用CPU的资源,简化编程模型,简化异步事件的处理,使GUI更有效率,节约成本。 下面是实现多线程下载的代码: package com.zyujie.util; import java.io.InputStream; import ...
  • java8线程异步常用的类

    千次阅读 2019-11-07 14:04:39
    1.java.lang包 接口 Runnable:提供一个无参的run(),其实例将由线程执行; Thread.UncaughtExceptionHandler(线程异常处理): - 当线程由于未捕获的异常而终止时,将调用该接口;...Thread(线程):java...
  • Java使用多线程异步执行批量更新操作

    千次阅读 热门讨论 2021-01-11 00:16:32
    因此,开多线程来执行批量任务是十分重要的一种批量操作思路,其实这种思路实现起来也十分简单,就拿批量更新的操作举例: 整体流程图 步骤 获取需要进行批量更新的大集合A,对大集合进行拆分操作,分成N个小集合A...
  • java创建线程总共有三种方式: 1.继承Thread类 2.实现runnable接口 3.实现Callable接口 他们三者的区别是Callable可以返回结果值,而前俩者无法返回结果值。假若我们的主线程需要子线程去执行异步操作获取数据...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 219,555
精华内容 87,822
关键字:

java多线程实现异步

java 订阅