Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使ExecutorService中的线程处于等待阶段_Java_Multithreading_Spring Boot_Java Stream_Executorservice - Fatal编程技术网

Java 如何使ExecutorService中的线程处于等待阶段

Java 如何使ExecutorService中的线程处于等待阶段,java,multithreading,spring-boot,java-stream,executorservice,Java,Multithreading,Spring Boot,Java Stream,Executorservice,在我的web应用程序中,我需要在一个API调用中调用大约10个以上的方法。为了提高效率,我使用ExecutorService同时创建多个线程。每个返回不同对象的方法都期望fav_a()、fav_b()、fav_c()。(为了方便起见,下面给出了示例代码) @GetMapping(RequestUrl.INIT) public ResponseEntity>map=new HashMap(); put(“方法a”,方法a.get()); put(“method_b”,method_b.get())

在我的web应用程序中,我需要在一个API调用中调用大约10个以上的方法。为了提高效率,我使用
ExecutorService
同时创建多个线程。每个返回不同对象的方法都期望
fav_a()、fav_b()、fav_c()
。(为了方便起见,下面给出了示例代码)

@GetMapping(RequestUrl.INIT)
public ResponseEntity>map=new HashMap();
put(“方法a”,方法a.get());
put(“method_b”,method_b.get());
put(“method_c”,method_c.get());
地图。放置(“收藏夹”,组合收藏夹);
返回新的响应属性(map,HttpStatus.OK);
}
首先,我需要获得
fav_a.get(),fav_b.get(),fav_c.get()
来制作
combinedFavorite
。如果其中任何一个延迟,逻辑将是错误的。创建线程非常昂贵

  • Stream
    是否自动处理这种情况
  • 如果
    fav_a()、fav_b()、fav_c()
    比其他方法更早完成任务,我如何将
    CombinedFavorite
    放入另一个线程?这意味着如何在等待阶段制作
    未来组合收藏夹
    ,直到
    fav_a.get()、fav_b.get()、fav_c.get()
    完成。(假设
    方法a()、方法b()、方法c()
    仍在运行。)
  • 不,流不负责连接这些线程

  • 因为您等待这3个线程的结果并将它们放入一个映射中,然后返回,所以在单独的线程中包装这样的逻辑对您没有帮助,因为您必须等待并返回结果

    用于执行所有任务并在所有任务完成时返回未来列表(当
    Future::done
    true
    时)

    List List=service.invokeAll(
    Arrays.asList(
    ()->someService.method_a(),
    ()->someService.method_b(),
    ()->someService.method_c()
    ));
    
    注意:这些是有保证的:

    • 结果
      列表
      与给定任务集合的顺序相同(根据其
      迭代器
    • 如果线程池中的线程数高于或等于已执行的任务数(假设没有其他任务使用同一线程池中的线程),则所有任务都将在单独的线程中运行

  • 此逻辑帮助您获得完整的结果。

    很好的解释。这是否意味着,我需要使用两个
    invokeAll()
    来设置
    method_a()、method_b()、method_c()
    和set
    fav_a()、fav_b()、fav_c()
    ,然后在
    fav
    设置中使用
    isDone()
    ,在关闭前我可以分配一次线程执行
    combinedFav
    ,我将使用两个
    invokeAll()
    方法(使线程池足够大)。只要
    invokeAll
    等待并保证所有的未来都完成,就不需要使用
    Future::isDone
    Future::isDone
    对于所有的未来都是
    true
    )。另请注意,
    ExecutorService::shutdown
    实际上并不会立即关闭服务,而是发送一个关闭请求-它会将服务的状态更改为类似“关机”的状态,这意味着它拒绝新任务,但会完成正在进行的任务。非常感谢,工作正常。由于我需要将所有服务放在map中,所以我可以通过获取列表的索引来获得结果,不是吗?是的,结果的顺序与任务的顺序相同。有趣的问题,@Nikolas我创建了三个具有不同睡眠时间的线程
    Future a=service.submit(()->{System.out.println(“First third starts”);Thread.sleep(10000);return“第一个线程”;});
    然后我做的是,
    Stream.of(a.get(),b.get(),c.get()).collect(collector.toList());
    它返回所有三个方法的结果。流被
    .get()
    阻止了吗??
    @GetMapping(RequestUrl.INIT)
    public ResponseEntity<Map<String, List<?>>> init() throws ExecutionException, InterruptedException {
    
        ExecutorService service = Executors.newFixedThreadPool(6);
    
        Future<List<Object>> method_a = service.submit(() -> someService.method_a());
        Future<List<Object>> method_b = service.submit(() -> someService.method_b());
        Future<List<Object>> method_c = service.submit(() -> someService.method_c());       
        
        Future<List<FavouriteConverter>> fav_a = service.submit(() -> someService.fav_a());
        Future<List<FavouriteConverter>> fav_b = service.submit(() -> someService.fav_b());
        Future<List<FavouriteConverter>> fav_c = service.submit(() -> someService.fav_c());
    
        service.shutdown();
    
        List<FavouriteConverter> combinedFavourite = Stream.of(fav_a.get(), fav_b.get(), fav_c.get()).flatMap(f -> f.stream()).collect(Collectors.toList());
        combinedFavourite=combinedFavourite.stream()
                .sorted(Comparator.comparing(FavouriteConverter::get_id, Comparator.reverseOrder()))
                .limit(25)
                .collect(Collectors.toList());
    
        Map<String, List<?>> map = new HashMap<>();    
    
        map.put("method_a", method_a.get());
        map.put("method_b", method_b.get());
        map.put("method_c", method_c.get());
        map.put("favourite", combinedFavourite);
    
        return new ResponseEntity<>(map, HttpStatus.OK);
    
    }
    
    List<Future<List<Object>>> list = service.invokeAll(
        Arrays.asList(
            () -> someService.method_a(),
            () -> someService.method_b(),
            () -> someService.method_c()
    ));