How to send multiple asynchronous requests to different web services?

后端 未结 6 1337
梦谈多话
梦谈多话 2021-02-01 07:27

I need to send multiple requests to many different web services and receive the results. The problem is that, if I send the requests one by one it takes so long as I need to sen

6条回答
  •  野的像风
    2021-02-01 08:05

    That is a simple fork-join approach, but for clarity, you can start any number of threads and retrieve the results later as they are available, such as this approach.

        ExecutorService pool = Executors.newFixedThreadPool(10);
        List> tasks = new ArrayList<>();
        tasks.add(new Callable() {
            public String call() throws Exception {
                Thread.sleep((new Random().nextInt(5000)) + 500);
                return "Hello world";
            }
    
        });
        List> results = pool.invokeAll(tasks);
    
        for (Future future : results) {
            System.out.println(future.get());
        }
        pool.shutdown();
    

    UPDATE, COMPLETE:

    Here's a verbose, but workable solution. I wrote it ad hoc, and have not compiled it. Given the three lists have diffent types, and the WS methods are individual, it is not really modular, but try to use your best programming skills and see if you can modularize it a bit better.

        ExecutorService pool = Executors.newFixedThreadPool(10);
    
        List>> stasks = new ArrayList<>();
        List>> dtasks = new ArrayList<>();
        List>> ptasks = new ArrayList<>();
    
        stasks.add(new Callable>() {
            public List call() throws Exception {
                return retrieveStdWS1();
            }
    
        });
        stasks.add(new Callable>() {
            public List call() throws Exception {
                return retrieveStdWS2();
            }
    
        });
        stasks.add(new Callable>() {
            public List call() throws Exception {
                return retrieveStdWS3();
            }
    
        });
    
        dtasks.add(new Callable>() {
            public List call() throws Exception {
                return retrieveDocWS4();
            }
    
        });
        dtasks.add(new Callable>() {
            public List call() throws Exception {
                return retrieveDocWS5();
            }
    
        });
        dtasks.add(new Callable>() {
            public List call() throws Exception {
                return retrieveDocWS6();
            }
    
        });
    
        ptasks.add(new Callable>() {
            public List call() throws Exception {
                return retrievePtWS7();
            }
    
        });
        ptasks.add(new Callable>() {
            public List call() throws Exception {
                return retrievePtWS8();
            }
    
        });
        ptasks.add(new Callable>() {
            public List call() throws Exception {
                return retrievePtWS9();
            }
    
        });
    
        List>> sresults = pool.invokeAll(stasks);
        List>> dresults = pool.invokeAll(dtasks);
        List>> presults = pool.invokeAll(ptasks);
    
        for (Future> future : sresults) {
           this.studentsResults.addAll(future.get());
        }
        for (Future> future : dresults) {
           this.doctorsResults.addAll(future.get());
        }
        for (Future> future : presults) {
           this.patientsResults.addAll(future.get());
        }
        pool.shutdown();
    

    Each Callable returns a list of results, and is called in its own separate thread.
    When you invoke the Future.get() method you get the result back onto the main thread.
    The result is NOT available until the Callable have finished, hence there is no concurrency issues.

提交回复
热议问题