рдлрд┐рд░ рд╕реЗ рдирдорд╕реНрдХрд╛рд░ред рдкрд╛рдареНрдпрдХреНрд░рдо рдХреА рд╢реБрд░реБрдЖрдд рдХреА рдкреНрд░рддреНрдпрд╛рд╢рд╛ рдореЗрдВ "рдЬрд╛рд╡рд╛ рдбреЗрд╡рд▓рдкрд░" рдиреЗ рдЖрдкрдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╕рд╛рдордЧреНрд░реА рдХрд╛ рдЕрдиреБрд╡рд╛рдж рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ред
CompletableFuture
рдореЗрдВ рджреЛ рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реИрдВ рдЬрд┐рдирдХреА рдбрд┐рдЬрд╝рд╛рдЗрди рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рдХрд░рддреА рд╣реИ:
- рдХрдВрдкреНрд▓реАрдЯрдЯреЗрдмрд▓ рд╕реАрд╡рди # allOf
- рдХрдВрдкреНрд▓реАрдЯрдЯреЗрдмрд▓ рд╕рд┐рд╡рдиреА # anyOf
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдЙрдирдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдЧрд▓рдд рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдХреИрд╕реЗ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдХрдВрдкреНрд▓реАрдЯрдЯреЗрдмрд▓ рд╕реАрд╡рди # allOf
рдЖрдЗрдП рд╡рд┐рдзрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдкрд░ рдирдЬрд░ рдбрд╛рд▓реЗрдВ:
public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) {
рдпрд╣рд╛рдВ рдХрдо рд╕реЗ рдХрдо рджреЛ рд╡рд┐рд╡рд╛рджрд╛рд╕реНрдкрдж рдореБрджреНрджреЗ рд╣реИрдВ:
- рдпрд╣ рд╡рд┐рдзрд┐ рдХрдИ
CompletableFuture
рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреА рд╣реИ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ CompletableFuture
ред - рдореЗрдердб
CompletableFuture
, рдЬреЛ Void
рджреЗрддрд╛ рд╣реИ
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХреБрдЫ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдЪрд░ рд╕рдВрдЦреНрдпрд╛ рдкрд╕рдВрдж рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдЖрдЗрдП рдЗрд╕ рднрд╛рдЧ рдХреЛ рднреА рджреЗрдЦреЗрдВред
CompletableFuture<Void>
рдЕрдХреНрд╕рд░ рдХрд┐рд╕реА рдСрдкрд░реЗрд╢рди рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рдЧреНрдирд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ; рд╣рд╛рд▓рд╛рдБрдХрд┐, рдПрдкреАрдЖрдИ рдореЗрдВ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдХреЗ,
рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рд╕рд┐рдЧреНрдирд▓рд┐рдВрдЧ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдФрд░ рд╕рднреА рдкреВрд░реНрдг рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рд╡рд╛рд╣рдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред рдЪрд▓реЛ рдЗрд╕реЗ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВред
рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдХрдВрдкреНрд▓реАрдЯрдЯреЗрдмрд▓ рд╕рд┐рд╡рдиреА # рдСрд▓рдСрдл
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЪрд▓реЛ рд╕рд╣реА рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рд╕рд╛рде рдЖрддреЗ рд╣реИрдВред
рдпрд╣ рдорд╛рди рд▓реЗрдирд╛ рдЙрдЪрд┐рдд рд╣реИ рдХрд┐ рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╕рдЬрд╛рддреАрдп
CompletableFuture
рдХреА рдПрдХ рд╕реВрдЪреА рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдФрд░ рдПрдХ
CompletableFuture
рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЬрд┐рд╕рдореЗрдВ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рд╕реВрдЪреА рд╣реЛрдЧреА, рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:
public static <T> CompletableFuture<List<T>> allOf( Collection<CompletableFuture<T>> futures) {
рдореВрд▓ рд╡рд┐рдзрд┐ рдХрд╛ рдЕрдВрддрд░ рдЖрдкрдХреА рдЕрдкреЗрдХреНрд╖рд╛ рд╕реЗ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ:
static CompletableFuture<Void> andTree( CompletableFuture<?>[] cfs, int lo, int hi) { CompletableFuture<Void> d = new CompletableFuture<Void>(); if (lo > hi)
рдЗрд╕рд▓рд┐рдП, рдЗрд╕реЗ рд╕реНрдХреНрд░реИрдЪ рд╕реЗ рдмрдирд╛рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдореВрд▓ рд╡рд┐рдзрд┐ рдореЗрдВ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ рдЗрд╕реЗ рдПрдХ рдкреВрд░реНрдг рд╕рд┐рдЧреНрдирд▓рд┐рдВрдЧ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдЗрд░рд╛рджрд╛ рдерд╛ ... рдФрд░ рдлрд┐рд░ рд╢реВрдиреНрдп рдкрд░рд┐рдгрд╛рдо рдХреЛ рднрд╡рд┐рд╖реНрдп рдХреА рд╕реВрдЪреА рдореЗрдВ рдмрджрд▓ рджреЗрдВ:
CompletableFuture<List<CompletableFuture<T>>> i = futures.stream() .collect(collectingAndThen( toList(), l -> CompletableFuture.allOf(l.toArray(new CompletableFuture[0])) .thenApply(__ -> l)));
рдЕрднреА рддрдХ рддреЛ рдЕрдЪреНрдЫрд╛ рд╣реИред рд╣рдо рдкрд╛рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣реЗ
CompletableFuture<List<CompletableFuture<T> >
>
рдмрдЬрд╛рдп
CompletableFuture<List<CompletableFuture<T> >
>
CompletableFuture<Void>
рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдЪреНрдЫрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рд╕рд╛рде рднрд╡рд┐рд╖реНрдп рдХреА рд╕реВрдЪреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд╣рдореЗрдВ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рд╕реВрдЪреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдЕрдм рд╣рдо рдХреЗрд╡рд▓ рд╕реВрдЪреА рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдореЗрдВ рд╕реЗ рдЕрд╡рд╛рдВрдЫрд┐рдд рднрд╡рд┐рд╖реНрдп рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред рдХрдВрдкреНрд▓реАрдЯрдЯреЗрдмрд▓ рд╕рд┐рд╡рдиреА # рдЬреЙрдЗрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рдХрднреА рднреА рдЕрд╡рд░реБрджреНрдз рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ (рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рд╕рднреА рднрд╡рд┐рд╖реНрдп рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреВрд░реЗ рд╣реЛ рдЪреБрдХреЗ рд╣реИрдВ):
CompletableFuture<List<T>> result = intermediate .thenApply(list -> list.stream() .map(CompletableFuture::join) .collect(toList()));
рдЕрдм рдЗрд╕ рд╕рдм рдХреЛ рдПрдХ рдЕрдВрддрд┐рдо рд╣рд▓ рдореЗрдВ рдорд┐рд▓рд╛рддреЗ рд╣реИрдВ:
public static <T> CompletableFuture<List<T>> allOf( Collection<CompletableFuture<T>> futures) { return futures.stream() .collect(collectingAndThen( toList(), l -> CompletableFuture.allOf(l.toArray(new CompletableFuture[0])) .thenApply(__ -> l.stream() .map(CompletableFuture::join) .collect(Collectors.toList())))); }
рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдФрд░ рдлреЙрд▓рд┐рдВрдЧ рдХрдореНрдкреЗрдЯрд┐рдмрд▓рдлреНрдпреВрдЪрд░ # allOf
рдпрджрд┐ рдЕрдкрд╡рд╛рдж рд╣реИрдВ, рддреЛ рдореВрд▓ рдХрдВрдкреЛрдЬрд╝рд┐рдмрд▓рдлрд╝реНрдпреВрдЬрд╝рди # allOf рд╕рднреА рд╢реЗрд╖ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИред
рдФрд░ рдЕрдЧрд░ рд╣рдо рдЗрд╕рдореЗрдВ рдЕрдкрд╡рд╛рдж рд╣реЛрдиреЗ рдкрд░ рдСрдкрд░реЗрд╢рди рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП,
CompletableFuture
рдХрд╛ рдПрдХ рдирдпрд╛ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдПрдВ рдФрд░ рдСрдкрд░реЗрд╢рди рдХреЗ рдПрдХ рдЕрдкрд╡рд╛рдж рдХреЗ рдмрд╛рдж рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЗрд╕реЗ рд╕рдорд╛рдкреНрдд рдХрд░реЗрдВ:
CompletableFuture<List<T>> result = new CompletableFuture<>(); futures.forEach(f -> f .handle((__, ex) -> ex == null || result.completeExceptionally(ex)));
... рд▓реЗрдХрд┐рди рддрдм рд╣рдореЗрдВ рдкрд░рд┐рджреГрд╢реНрдп рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдЬрдм рд╕рднреА рднрд╡рд┐рд╖реНрдп рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкреВрд░рд╛ рд╣реЛ рдЬрд╛рдПрдВрдЧреЗред рдпрд╣ рдЖрд╕рд╛рдиреА рд╕реЗ рдмреЗрд╣рддрд░ рдСрд▓рдл () рдкрджреНрдзрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдмрд╕ рднрд╡рд┐рд╖реНрдп рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╕рдорд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ:
allOf(futures).thenAccept(result::complete);
рдЕрдм рд╣рдо рдЕрдВрддрд┐рдо рд╕рдорд╛рдзрд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдм рдХреБрдЫ рдПрдХ рд╕рд╛рде рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:
public static <T> CompletableFuture<List<T>> allOfShortcircuiting(Collection<CompletableFuture<T>> futures) { CompletableFuture<List<T>> result = new CompletableFuture<>(); for (CompletableFuture<?> f : futures) { f.handle((__, ex) -> ex == null || result.completeExceptionally(ex)); } allOf(futures).thenAccept(result::complete); return result; }
рдХрдВрдкреНрд▓реАрдЯрдЯреЗрдмрд▓ рд╕рд┐рд╡рдиреА # anyOf
рдЖрдЗрдП рд╡рд┐рдзрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ:
public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) {
рд╣рдо рддреБрд░рдВрдд рдЙрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдКрдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рд╣реИрдВ:
- рд╡рд┐рдзрд┐ рдХрдИ рдкреНрд░рдХрд╛рд░ рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рд╡рд╛рд▓реЗ рдХрдИ
CompletableFuture
рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреА рд╣реИред - рд╡рд┐рдзрд┐ рдПрдХ рдкреВрд░реНрдг рдкреНрд░рдХрд╛рд░ рдХрд╛
Object
рдпреБрдХреНрдд рдПрдХ CompletableFuture
рджреЗрддрд╛ рд╣реИред
рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛрдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ,
CompletableFuture#allOf
рдХреЛ рдПрдХ рд╕рд┐рдЧреНрдирд▓рд┐рдВрдЧ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд▓реЗрдХрд┐рди
CompletableFuture#anyOf
рдЗрд╕
CompletableFuture#anyOf
рдХреЛ рдлреЙрд▓реЛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ,
CompletableFuture#anyOf
CompletableFuture<Object>
рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдФрд░ рднреА рднреНрд░рд╛рдордХ рд╣реИред
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ рдЬрд╣рд╛рдБ рдореИрдВ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдбреЗрдЯрд╛ рдпреБрдХреНрдд рдХрдВрдкреНрд▓реАрдЯрдЯреЗрдмрд▓ рд╕рд┐рд╡рдиреА рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣рд╛ рд╣реВрдБ:
CompletableFuture<Integer> f1 = CompletableFuture.completedFuture(1); CompletableFuture<String> f2 = CompletableFuture.completedFuture("2"); Integer result = CompletableFuture.anyOf(f1, f2) .thenApply(r -> { if (r instanceof Integer) { return (Integer) r; } else if (r instanceof String) { return Integer.valueOf((String) r); } throw new IllegalStateException("unexpected object type!"); }).join();
рдмрд╣реБрдд рдЕрд╕рд╣рдЬ рд╣реИ, рд╣реИ рдирд╛?
рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдмрджрд▓рдиреЗ рдФрд░ рдкреНрд░рддреНрдпрдХреНрд╖ рдкреНрд░рдХрд╛рд░ рдХреА рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп рдкрд░рд┐рджреГрд╢реНрдп (рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдХрдИ рднрд╡рд┐рд╖реНрдп рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдирд╛) рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдорд╛рд░реЗ рд╕реБрдзрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде, рд╣рдо рдореМрдЬреВрджрд╛ рддрд░реАрдХреЛрдВ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдкрд░рд┐рдгрд╛рдо рд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ:
public static <T> CompletableFuture<T> anyOf(List<CompletableFuture<T>> cfs) { return CompletableFuture.anyOf(cfs.toArray(new CompletableFuture[0])) .thenApply(o -> (T) o); } public static <T> CompletableFuture<T> anyOf(CompletableFuture<T>... cfs) { return CompletableFuture.anyOf(cfs).thenApply(o -> (T) o); }
рд╕реНрд░реЛрдд рдХреЛрдб
рд╕реНрд░реЛрдд рдХреЛрдб
Github рдкрд░ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╡рд╣ рд╕рдм рд╣реИред
рдХреЛрд░реНрд╕ рдкрд░
рдорд┐рд▓рддреЗ рд╣реИрдВ ред