SlideShare uma empresa Scribd logo
1 de 32
Baixar para ler offline
Completable

Future
THREADSCONCORRÊNCIAE
PARALELISMOEMJAVA
Helder da Rocha (helder@summa.com.br)
10
1. Criação e controle de threads
2. Acesso exclusivo e comunicação entre threads
3. Ciclo de vida, aplicações e boas práticas
4. Variáveis atômicas
5. Travas
6. Coleções
7. Sincronizadores
8. Executores e Futures
9. Paralelismo
10. CompletableFuture
THREADSCONCORRÊNCIAE
PARALELISMOEMJAVA
APICompletableFuture
• API de execução assíncrona, funcional, baseada em fluxos de dados reativos
introduzida no Java 8
• Consiste da interface CompletionStage e sua implementação: a classe
CompletableFuture.
• Possui mais de 70 métodos.
• Métodos recebem interfaces funcionais e retornam CompletionStage
(podem ser concatenados)
• Programação similar a API de streams (mas usa push, em vez de pull)
CompletionStage
CompletableFuture<V>
CompletionStage<V>Future<V>
• Um CompletableFuture é um Future e também um CompletionStage:
interface que representa uma computação possivelmente assíncrona
• Um CompletableFuture é corrente de CompletionStages concatenados.
• Cada CompletionStage executa uma etapa da tarefa. Cada etapa é executada
quando a anterior termina, podendo usar seu resultado como entrada.
CompletionStage CompletionStage CompletionStage
CompletionStage
• O primeiro elemento da corrente deve ser uma tarefa descrita pela
interface funcional Runnable ou Supplier<T>.
• Os estágios seguintes podem conter tarefas descritas pelas seguintes
interfaces funcionais:
• Consumer<T> (se não retornam valor)
• Function<T,R> (se recebem valor e retornam outro)
• Runnable (se não recebem nem passam valor adiante)
Concatenaçãodeestágios
CompletableFuture
supplyAsync
() -> event.get()
CompletionStage
thenApply
x -> x * x
CompletionStage
thenAccept
x -> System.out.println(x)
CompletionStage
thenRun
() -> System.out.println("Done!")
triggers
triggers
triggers
• A execução de um estágio é
disparada pela conclusão de
um estágio anterior
• Também pode esperar dois
estágios ou um dentre dois
estágios anteriores
• Também é possível combinar
resultados.
Um evento pode completar um
CompletableFuture chamando
complete(valor)
ComocriarumCompletableFuture
• Usando o construtor default
CompletableFuture<Integer> trigger = new CompletableFuture<>();
• CompletableFuture pode ser completado explicitamente usando
complete(valor) ou completeAsync(Supplier)
trigger.complete(5);
• Um callback (esperando no get()) que executará depois do complete()
new Thread(() -> {
try {
System.out.println("Resultado da tarefa: " + trigger.get());
} catch (InterruptedException | ExecutionException e) { ... }
}).start();
ComocriarumCompletableFuture
• Usando métodos de fábrica e uma tarefa Runnable ou Supplier<V>
• CompletableFuture.runAsync( Runnable tarefa)

• CompletableFuture.supplyAsync( Supplier<T> tarefa)
CompletableFuture<Void> cf1 = CompletableFuture.runAsync(() -> {
for (int i = 0; i < 1_000_000_000; i++)
if (i % 100_000_000 == 0)
System.out.print("2");
});
CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 1_000_000_000; i++)
if (i % 100_000_000 == 0)
builder.append((char)(new Random().nextInt(26) + 'A'));
return builder.toString();
});
Estágiosiniciais
()
void R res
Runnable
«interface»
void run()
Supplier<R>
«interface»
R get()
CompletionStage
runAsync
() -> void
CompletionStage
supplyAsync
() -> r
()
thenRun
• Recebe interface funcional Runnable

run()
• Tarefas podem não recebem resultado e não produzem
• Um estágio thenRun pode ser usado para callbacks que não dependem
de valores de tarefas anteriores
CompletableFuture.runAsync(() -> {
for (int i = 0; i < 1_000_000_000; i++)
if (i % 100_000_000 == 0)
System.out.print("2");
}).thenRun(() -> System.out.println("DONE"));
thenAccept
• Recebe interface funcional Consumer<T>

accept(T valor)
• Tarefas podem receber um resultado (mas não produzem)
• Um estágio thenAccept pode ser usado no final de uma cadeia
CompletableFuture.supplyAsync(() -> {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 1_000_000_000; i++)
if (i % 100_000_000 == 0)
builder.append((char)(new Random().nextInt(26) + 'A'));
return builder.toString();
}).thenAccept(result -> System.out.println("Result is: " + result));
thenApply
TagOperations to = new TagOperations();
CompletableFuture.supplyAsync(() -> "text")
.thenApply(s -> to.tag("p", s))
.thenApply(s -> s.concat("n"))
.thenApply(s -> "n".concat(s))
.thenApply(s -> to.tag("div", s))
.thenAccept(s -> 

System.out.println("Result:n" + s));
class TagOperations {
String tag(String tagName, 

String contents) {...}
String unTag(String taggedText) {...}
}
• Recebe interface funcional
Function<T,R>

R apply(T valor)
• Tarefas podem receber um
resultado e produzir outro.
• Vários estágios thenApply
podem ser concatenados
Estágiosintermediários
()
void
T val
void R res
T val
Runnable
«interface»
void run()
Consumer<T>
«interface»
void accept(T val)
Function<T,R>
«interface»
R apply(T val)
CompletionStage
thenRun
() -> void
CompletionStage
thenAccept
t -> void
CompletionStage
thenApply
t -> r
Estágiossíncronos
• Cada estágio é executado no mesmo
thread do estágio anterior, exceto se o
método terminar em Async
• Um estágio inicia apenas quando o
estágio anterior termina (isto vale para
estágios comuns e Async).
• Se o estágio anterior produzir um
resultado, o valor poderá ser usado pelo
estágio seguinte
main
future
future.join()
forkjoin-pool

thread-1
complete()
complete()
complete()
complete()
complete()
thenAccept
supplyAsync
thenApply
thenApply
thenApply
main
future
future.join()
forkjoin-pool

thread-1
forkjoin-pool

thread-2
forkjoin-pool

thread-3
complete()
complete()
complete()
complete()
complete()
thenAccept
supplyAsync
thenApply
thenApplyAsync
thenApplyAsync
Estágios
Async
• Se o método terminar em
Async, o a tarefa é
executada em novo thread
• Mesmo em threads
diferentes, um estágio
seguinte só inicia quando o
anterior é completado
Execuçãosimultânea
main
future
forkjoin-pool

thread-1
forkjoin-pool

thread-2
supplyAsync
thenApply
thenApplyAsync
future
thenApply
future
complete()
complete()
complete()
main
future
forkjoin-pool

thread-1
supplyAsync
thenApply
future
future
complete()
complete()
complete()
• É possível em estágios Async que fazem parte de correntes diferentes
EscolhadoExecutorService
• Os métodos Async permitem a escolha do serviço de execução
(ExecutorService) que será usado pela tarefa
ExecutorService executor = Executors.newSingleThreadExecutor();
CompletableFuture.supplyAsync(() -> loadFile("dictionary.csv"))
.thenApply(data -> csvParser.parse(data))
.thenApply(data -> dataVizGenerator.lineChart(data))
.thenAcceptAsync(chart -> workspace.display(chart), executor);
main thread
fork-join-pool thread
executor thread
Exceções
• Se um CompletionStage provocar uma exceção, ela será encapsulada
dentro de uma CompletionException
• A exceção é propagada pelos CompletionStages que vierem depois.
• isCompletedExceptionally() retornará true
• Se get() for chamado será lançada uma ExecutionException
exceptionally
• Funciona como bloco catch
• Recebe Function<Throwable,T>
• Pode substituir exceção por um valor válido
CompletableFuture.supplyAsync(()->1/0)
.exceptionally(e->0)
.thenAccept(n->System.out::println));
handle
• Recebe BiFunction<T,Throwable, R>
• Etapa completa normalmente e repassa resultado adiante.
• Se houver exceção, resultado é null, mas exceção poderá ser utilizada.
• Se a operação completar normalmente, a exceção será null.
CompletableFuture.supplyAsync(()->1/0)
.handle((data, error) -> {
if(error != null) {
return 0;
} else return data;
})
.thenAcceptAsync(s -> System.out.println("Result:" + s));
whenComplete
• Recebe um BiConsumer<T,Throwable>
• Não tem como tratar a exceção (alterar o valor que é passado adiante)
CompletableFuture.supplyAsync(()->1/0)
.whenComplete((data, error) -> {
if(error != null) {
System.out.println("Error: " + error);
}
})
.exceptionally(e -> 0)
.thenAccept(n->System.out::println));
Estágiosquecapturamexceções
void R r
BiConsumer<T,U>
«interface»
void accept(T val,Throwable e)
BiFunction<T,Throwable,R>
«interface»
R apply(T val,Throwable e)
CompletionStage
exceptionally
e -> r
CompletionStage
whenComplete
(t, e) -> void
CompletionStage
handle
(t, e) -> r
T val Throwable eThrowable e
Function<Throwable,R>
«interface»
R apply(Throwable e)
R r
T val Throwable e
CompletionException
• Exceções são encapsuladas em CompletionException (podem ser
extraídas usando getCause())
• Nas expressões dos métodos exceptionally() e handle() a exceção é
automaticamente desempacotada
java.util.concurrent.CompletionException
getCause()java.io.IOException
Desempacotamentoautomático
java.io.IOException
CompletionStage
thenApply
out -> out.println("text")
CompletionStage
exceptionally
e -> System.out.println(e)
CompletionStage
thenApply
out -> out.println("text")
CompletionStage
handle
(d,e) -> System.out.println(e)
java.io.IOException
java.io.IOException
java.io.IOException
CompletionStage
thenApply
out -> out.println("text")
CompletionStage
whenComplete
(d,e) -> System.out.println(e)
java.io.IOException
j.u.c.CompletionException
• IOException provocada em um estágio e automaticamente desempacotada
em exceptionally() e handle(), mas não em whenComplete()
CombinaçãoAND
• Estágios que esperam que dois estágios anteriores completem
• runAfterBoth()
• thenAcceptBoth()
• thenCombine()
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");
future1.runAfterBoth(future2, ()-> System.out.println("future1 e future2 terminaram!"));
future1.thenAcceptBoth(future2, (f1,f2)->
System.out.println("Result: " + f1 + " " + f2 + "!")));
CompletableFuture<Integer> future3 = future2.thenApply(s -> s.length());
CompletableFuture<Integer> future4 =
future1.thenCombine(future3, (f1,f3)-> f1.length() + f3);
CombinaçãoAND
()
void void R res
Runnable
«interface»
void run()
BiConsumer<T,U>
«interface»
void accept(T val1, U val2)
BiFunction<T,U,R>
«interface»
R apply(T val1, U val2)
CompletionStage
runAfterBoth
() -> void
CompletionStage
thenAcceptBoth
(t, u) -> void
CompletionStage
thenCombine
(t, u) -> r
T val1 U val2 T val1 U val2
CombinaçãoOR
• Estágios que esperam que um, dentre dois estágios anteriores, complete
• runAfterEither()
• acceptEither()

• applyToEither()
future1.runAfterEither(future2,
() -> System.out.println("Terminou future1 ou future2"));
future1.acceptEither(future2,
s -> System.out.println(s)); // imprime “Hello” ou “World”
future1.applyToEither(future2, s -> s.toUpperCase())
.thenAccept(s -> System.out.println(s)); // imprime “HELLO” ou “WORLD”
CombinaçãoOR
()
void void R res
T val
CompletionStage
runEither
() -> void
CompletionStage
acceptEither
t -> void
CompletionStage
applyToEither
t -> r
T val
Runnable
«interface»
void run()
Consumer<T>
«interface»
void accept(T val)
Function<T,R>
«interface»
R apply(T val)
Composiçaodeestágios
• thenCompose()

• Análogo ao método flatMap() de Stream
CompletionStage
thenCompose
t -> stage
CompletionStage stage
T val
Function<T,CompletionStage>
«interface»
CompletionStage apply(T val)
CompletableFuture<String> stage1 =
new CompletableFuture<>();
CompletableFuture<String> stage2 =
CompletableFuture.supplyAsync(() -> "World");
CompletableFuture<CompletableFuture<String>> stage3 =
stage1.thenApply(s1 ->
stage2.thenApply(s2 -> s1 + s2.toUpperCase()));
stage3.thenAccept(cf -> System.out.println("S3: " + cf.join()));
CompletableFuture<String> stage4 =
stage1.thenCompose(s1 ->
stage2.thenApply(s2 -> s1 + s2.toUpperCase()));
stage4.thenAccept(s -> System.out.println("S4: " + s));
stage1.complete("Hello, ");
stage1.join();
CombinaçãoeseleçãodeCompletableFutures
• anyOf() retorna CompletableFuture que é completado assim que um dos
CompletableFutures da lista completar
• allOf() retorna CompletableFuture que é completado quando todos os
CompletableFutures da lista completarem.
List<CompletableFuture<?>> fs = List.of(f1, f2, f3, f4);
CompletableFuture<?>[] array = fs.toArray(new CompletableFuture[fs.size()]);
CompletableFuture<List<?>>> resultados = CompletableFuture.allOf(array)
.thenApply(v -> fs.stream().map(f -> f.join())
.collect(Collectors.toList()));
CompletableFuture<?> anyFuture = CompletableFuture.anyOf(array));
Outrosmétodos
• completedFuture(valor) 

• Retorna um CompletableFuture já completo e com o valor passado
como argumento. Útil para a construção de testes.
• completeExceptionally(throwable) 

• Chamadas a get(), join() e similares lançam exceção passada como
argumento, se CompletableFuture ainda não tiver completado a tarefa
• obtrudeValue(valor) e obtrudeException(throwable)
• Forçam retorno de valor diferente para get(), join() ou lançamento de
exceção diferente, independente da tarefa ter sido completada ou não
THREADSCONCORRÊNCIAE
PARALELISMOEMJAVA
Helder da Rocha (helder@summa.com.br)
github.com/helderdarocha/java8-course/
/java/concurrency/
Maio 2015

Mais conteúdo relacionado

Mais procurados

Aula de Introdução - JAVA
Aula de Introdução  - JAVAAula de Introdução  - JAVA
Aula de Introdução - JAVAMoises Omena
 
Curso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsCurso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsHelder da Rocha
 
Unit 1 - TypeScript & Introduction to Angular CLI.pptx
Unit 1 - TypeScript & Introduction to Angular CLI.pptxUnit 1 - TypeScript & Introduction to Angular CLI.pptx
Unit 1 - TypeScript & Introduction to Angular CLI.pptxMalla Reddy University
 
Linguagem de Programação Java para Iniciantes
Linguagem de Programação Java para IniciantesLinguagem de Programação Java para Iniciantes
Linguagem de Programação Java para IniciantesOziel Moreira Neto
 
Threads 01: Criação e controle de threads
Threads 01: Criação e controle de threadsThreads 01: Criação e controle de threads
Threads 01: Criação e controle de threadsHelder da Rocha
 
Introduction To Appium With Robotframework
Introduction To Appium With RobotframeworkIntroduction To Appium With Robotframework
Introduction To Appium With RobotframeworkSyam Sasi
 
[Curso Java Basico] Aula 12: Lendo dados do teclado usando a classe Scanner
[Curso Java Basico] Aula 12: Lendo dados do teclado usando a classe Scanner[Curso Java Basico] Aula 12: Lendo dados do teclado usando a classe Scanner
[Curso Java Basico] Aula 12: Lendo dados do teclado usando a classe ScannerLoiane Groner
 
Typescript Fundamentals
Typescript FundamentalsTypescript Fundamentals
Typescript FundamentalsSunny Sharma
 
Desvendando a linguagem JavaScript
Desvendando a linguagem JavaScriptDesvendando a linguagem JavaScript
Desvendando a linguagem JavaScriptRodrigo Branas
 
Java exception handling ppt
Java exception handling pptJava exception handling ppt
Java exception handling pptJavabynataraJ
 
Stored Procedures and Triggers
Stored Procedures and TriggersStored Procedures and Triggers
Stored Procedures and Triggersflaviognm
 
Threads 03: Ciclo de vida, aplicações e boas práticas
Threads 03: Ciclo de vida, aplicações e boas práticasThreads 03: Ciclo de vida, aplicações e boas práticas
Threads 03: Ciclo de vida, aplicações e boas práticasHelder da Rocha
 
Asynchronous programming
Asynchronous programmingAsynchronous programming
Asynchronous programmingFilip Ekberg
 

Mais procurados (20)

Aula de Introdução - JAVA
Aula de Introdução  - JAVAAula de Introdução  - JAVA
Aula de Introdução - JAVA
 
Curso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsCurso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e Streams
 
Unit 1 - TypeScript & Introduction to Angular CLI.pptx
Unit 1 - TypeScript & Introduction to Angular CLI.pptxUnit 1 - TypeScript & Introduction to Angular CLI.pptx
Unit 1 - TypeScript & Introduction to Angular CLI.pptx
 
Streams in Java 8
Streams in Java 8Streams in Java 8
Streams in Java 8
 
Linguagem de Programação Java para Iniciantes
Linguagem de Programação Java para IniciantesLinguagem de Programação Java para Iniciantes
Linguagem de Programação Java para Iniciantes
 
Threads 01: Criação e controle de threads
Threads 01: Criação e controle de threadsThreads 01: Criação e controle de threads
Threads 01: Criação e controle de threads
 
Introduction To Appium With Robotframework
Introduction To Appium With RobotframeworkIntroduction To Appium With Robotframework
Introduction To Appium With Robotframework
 
[Curso Java Basico] Aula 12: Lendo dados do teclado usando a classe Scanner
[Curso Java Basico] Aula 12: Lendo dados do teclado usando a classe Scanner[Curso Java Basico] Aula 12: Lendo dados do teclado usando a classe Scanner
[Curso Java Basico] Aula 12: Lendo dados do teclado usando a classe Scanner
 
Unit testing with JUnit
Unit testing with JUnitUnit testing with JUnit
Unit testing with JUnit
 
C# Events
C# EventsC# Events
C# Events
 
Typescript Fundamentals
Typescript FundamentalsTypescript Fundamentals
Typescript Fundamentals
 
Desvendando a linguagem JavaScript
Desvendando a linguagem JavaScriptDesvendando a linguagem JavaScript
Desvendando a linguagem JavaScript
 
Java exception handling ppt
Java exception handling pptJava exception handling ppt
Java exception handling ppt
 
Stored Procedures and Triggers
Stored Procedures and TriggersStored Procedures and Triggers
Stored Procedures and Triggers
 
Threads 03: Ciclo de vida, aplicações e boas práticas
Threads 03: Ciclo de vida, aplicações e boas práticasThreads 03: Ciclo de vida, aplicações e boas práticas
Threads 03: Ciclo de vida, aplicações e boas práticas
 
Curso javascript básico
Curso javascript básicoCurso javascript básico
Curso javascript básico
 
Unit testing with java
Unit testing with javaUnit testing with java
Unit testing with java
 
JQuery introduction
JQuery introductionJQuery introduction
JQuery introduction
 
Aula 8 - Comandos de Entrada e Saída
Aula 8 - Comandos de Entrada e SaídaAula 8 - Comandos de Entrada e Saída
Aula 8 - Comandos de Entrada e Saída
 
Asynchronous programming
Asynchronous programmingAsynchronous programming
Asynchronous programming
 

Semelhante a Threads 10: CompletableFuture

Utilitários para Programação Concorrente em Java (2005)
Utilitários para Programação Concorrente em Java (2005)Utilitários para Programação Concorrente em Java (2005)
Utilitários para Programação Concorrente em Java (2005)Helder da Rocha
 
Atualização Java 8 (2014)
Atualização Java 8 (2014)Atualização Java 8 (2014)
Atualização Java 8 (2014)Helder da Rocha
 
Usando POP com Programação Funcional
Usando POP com Programação FuncionalUsando POP com Programação Funcional
Usando POP com Programação FuncionalTales Andrade
 
Threads 07: Sincronizadores
Threads 07: SincronizadoresThreads 07: Sincronizadores
Threads 07: SincronizadoresHelder da Rocha
 
Servlets 3: o contexto assíncrono - JavaOne 2010 - Paulo Silveira
Servlets 3: o contexto assíncrono - JavaOne 2010 - Paulo SilveiraServlets 3: o contexto assíncrono - JavaOne 2010 - Paulo Silveira
Servlets 3: o contexto assíncrono - JavaOne 2010 - Paulo SilveiraCaelum
 
TDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a Coroutines
TDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a CoroutinesTDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a Coroutines
TDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a Coroutinestdc-globalcode
 
DOJO - TDD com C++
DOJO - TDD com C++DOJO - TDD com C++
DOJO - TDD com C++thiagodp
 
TDD em C++
TDD em C++TDD em C++
TDD em C++thiagodp
 
Mule esb teste parte 2
Mule esb teste   parte 2Mule esb teste   parte 2
Mule esb teste parte 2Jeison Barros
 
Curso Desenvolvimento WEB com PHP - PHP (parte 1)
Curso Desenvolvimento WEB com PHP - PHP (parte 1)Curso Desenvolvimento WEB com PHP - PHP (parte 1)
Curso Desenvolvimento WEB com PHP - PHP (parte 1)Willian Magalhães
 
Substituindo o request message no mule
Substituindo o request message no muleSubstituindo o request message no mule
Substituindo o request message no muleJeison Barros
 
Testes em Aplicações Web com Cactus
Testes em Aplicações Web com CactusTestes em Aplicações Web com Cactus
Testes em Aplicações Web com CactusDenis L Presciliano
 
8a. aula -_estrutura_de_controle_de_repeticao_-_while_java
8a. aula -_estrutura_de_controle_de_repeticao_-_while_java8a. aula -_estrutura_de_controle_de_repeticao_-_while_java
8a. aula -_estrutura_de_controle_de_repeticao_-_while_javaMirlem Pereira
 
Javascript para CSharpers 2 - Functions
Javascript para CSharpers   2 - FunctionsJavascript para CSharpers   2 - Functions
Javascript para CSharpers 2 - FunctionsWesley Lemos
 
JS Experience 2017 - Javascript Funcional
JS Experience 2017 - Javascript FuncionalJS Experience 2017 - Javascript Funcional
JS Experience 2017 - Javascript FuncionaliMasters
 
Quem espera sempre cansa
Quem espera sempre cansaQuem espera sempre cansa
Quem espera sempre cansaRicardo Bánffy
 

Semelhante a Threads 10: CompletableFuture (20)

Utilitários para Programação Concorrente em Java (2005)
Utilitários para Programação Concorrente em Java (2005)Utilitários para Programação Concorrente em Java (2005)
Utilitários para Programação Concorrente em Java (2005)
 
Jdbc e hibernate
Jdbc e hibernateJdbc e hibernate
Jdbc e hibernate
 
Atualização Java 8 (2014)
Atualização Java 8 (2014)Atualização Java 8 (2014)
Atualização Java 8 (2014)
 
Usando POP com Programação Funcional
Usando POP com Programação FuncionalUsando POP com Programação Funcional
Usando POP com Programação Funcional
 
Threads 07: Sincronizadores
Threads 07: SincronizadoresThreads 07: Sincronizadores
Threads 07: Sincronizadores
 
Servlets 3: o contexto assíncrono - JavaOne 2010 - Paulo Silveira
Servlets 3: o contexto assíncrono - JavaOne 2010 - Paulo SilveiraServlets 3: o contexto assíncrono - JavaOne 2010 - Paulo Silveira
Servlets 3: o contexto assíncrono - JavaOne 2010 - Paulo Silveira
 
TDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a Coroutines
TDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a CoroutinesTDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a Coroutines
TDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a Coroutines
 
DOJO - TDD com C++
DOJO - TDD com C++DOJO - TDD com C++
DOJO - TDD com C++
 
TDD em C++
TDD em C++TDD em C++
TDD em C++
 
Mule esb teste parte 2
Mule esb teste   parte 2Mule esb teste   parte 2
Mule esb teste parte 2
 
Curso Desenvolvimento WEB com PHP - PHP (parte 1)
Curso Desenvolvimento WEB com PHP - PHP (parte 1)Curso Desenvolvimento WEB com PHP - PHP (parte 1)
Curso Desenvolvimento WEB com PHP - PHP (parte 1)
 
Funções e procedimentos
Funções e procedimentosFunções e procedimentos
Funções e procedimentos
 
Substituindo o request message no mule
Substituindo o request message no muleSubstituindo o request message no mule
Substituindo o request message no mule
 
Aula 1 | Introdução a C++
Aula 1 | Introdução a C++Aula 1 | Introdução a C++
Aula 1 | Introdução a C++
 
Servlets
ServletsServlets
Servlets
 
Testes em Aplicações Web com Cactus
Testes em Aplicações Web com CactusTestes em Aplicações Web com Cactus
Testes em Aplicações Web com Cactus
 
8a. aula -_estrutura_de_controle_de_repeticao_-_while_java
8a. aula -_estrutura_de_controle_de_repeticao_-_while_java8a. aula -_estrutura_de_controle_de_repeticao_-_while_java
8a. aula -_estrutura_de_controle_de_repeticao_-_while_java
 
Javascript para CSharpers 2 - Functions
Javascript para CSharpers   2 - FunctionsJavascript para CSharpers   2 - Functions
Javascript para CSharpers 2 - Functions
 
JS Experience 2017 - Javascript Funcional
JS Experience 2017 - Javascript FuncionalJS Experience 2017 - Javascript Funcional
JS Experience 2017 - Javascript Funcional
 
Quem espera sempre cansa
Quem espera sempre cansaQuem espera sempre cansa
Quem espera sempre cansa
 

Mais de Helder da Rocha

Como criar um mapa temático interativo com dados abertos e D3.js
Como criar um mapa temático interativo com dados abertos e D3.jsComo criar um mapa temático interativo com dados abertos e D3.js
Como criar um mapa temático interativo com dados abertos e D3.jsHelder da Rocha
 
Transforming public data into thematic maps (TDC2019 presentation)
Transforming public data into thematic maps (TDC2019 presentation)Transforming public data into thematic maps (TDC2019 presentation)
Transforming public data into thematic maps (TDC2019 presentation)Helder da Rocha
 
TDC 2019: transformando 
dados
públicos
em mapas interativos
TDC 2019: transformando 
dados
públicos
em mapas interativosTDC 2019: transformando 
dados
públicos
em mapas interativos
TDC 2019: transformando 
dados
públicos
em mapas interativosHelder da Rocha
 
Padrões essenciais de mensageria para integração de sistemas
Padrões essenciais de mensageria para integração de sistemasPadrões essenciais de mensageria para integração de sistemas
Padrões essenciais de mensageria para integração de sistemasHelder da Rocha
 
Visualização de dados e a Web
Visualização de dados e a WebVisualização de dados e a Web
Visualização de dados e a WebHelder da Rocha
 
Eletrônica Criativa: criando circuitos com materiais alternativos
Eletrônica Criativa: criando circuitos com materiais alternativosEletrônica Criativa: criando circuitos com materiais alternativos
Eletrônica Criativa: criando circuitos com materiais alternativosHelder da Rocha
 
Introdução à Visualização de Dados (2015)
Introdução à Visualização de Dados (2015)Introdução à Visualização de Dados (2015)
Introdução à Visualização de Dados (2015)Helder da Rocha
 
API de segurança do Java EE 8
API de segurança do Java EE 8API de segurança do Java EE 8
API de segurança do Java EE 8Helder da Rocha
 
Curso de Java Persistence API (JPA) (Java EE 7)
Curso de Java Persistence API (JPA) (Java EE 7)Curso de Java Persistence API (JPA) (Java EE 7)
Curso de Java Persistence API (JPA) (Java EE 7)Helder da Rocha
 
Curso de Enterprise JavaBeans (EJB) (JavaEE 7)
Curso de Enterprise JavaBeans (EJB) (JavaEE 7)Curso de Enterprise JavaBeans (EJB) (JavaEE 7)
Curso de Enterprise JavaBeans (EJB) (JavaEE 7)Helder da Rocha
 
Introdução a JPA (2010)
Introdução a JPA (2010)Introdução a JPA (2010)
Introdução a JPA (2010)Helder da Rocha
 
Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)
Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)
Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)Helder da Rocha
 
Minicurso de Segurança em Java EE 7
Minicurso de Segurança em Java EE 7Minicurso de Segurança em Java EE 7
Minicurso de Segurança em Java EE 7Helder da Rocha
 
Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)Helder da Rocha
 
Threads 05: Travas de Exclusão Mútua
Threads 05: Travas de Exclusão MútuaThreads 05: Travas de Exclusão Mútua
Threads 05: Travas de Exclusão MútuaHelder da Rocha
 
Reconstruction of Pterosaurs using XPS
Reconstruction of Pterosaurs using XPSReconstruction of Pterosaurs using XPS
Reconstruction of Pterosaurs using XPSHelder da Rocha
 
A arquitetura modular do Java 9
A arquitetura modular do Java 9A arquitetura modular do Java 9
A arquitetura modular do Java 9Helder da Rocha
 
15 padrões de mensageria para integração de sistemas
15 padrões de mensageria para integração de sistemas15 padrões de mensageria para integração de sistemas
15 padrões de mensageria para integração de sistemasHelder da Rocha
 

Mais de Helder da Rocha (19)

Como criar um mapa temático interativo com dados abertos e D3.js
Como criar um mapa temático interativo com dados abertos e D3.jsComo criar um mapa temático interativo com dados abertos e D3.js
Como criar um mapa temático interativo com dados abertos e D3.js
 
Transforming public data into thematic maps (TDC2019 presentation)
Transforming public data into thematic maps (TDC2019 presentation)Transforming public data into thematic maps (TDC2019 presentation)
Transforming public data into thematic maps (TDC2019 presentation)
 
TDC 2019: transformando 
dados
públicos
em mapas interativos
TDC 2019: transformando 
dados
públicos
em mapas interativosTDC 2019: transformando 
dados
públicos
em mapas interativos
TDC 2019: transformando 
dados
públicos
em mapas interativos
 
Padrões essenciais de mensageria para integração de sistemas
Padrões essenciais de mensageria para integração de sistemasPadrões essenciais de mensageria para integração de sistemas
Padrões essenciais de mensageria para integração de sistemas
 
Visualização de dados e a Web
Visualização de dados e a WebVisualização de dados e a Web
Visualização de dados e a Web
 
Eletrônica Criativa: criando circuitos com materiais alternativos
Eletrônica Criativa: criando circuitos com materiais alternativosEletrônica Criativa: criando circuitos com materiais alternativos
Eletrônica Criativa: criando circuitos com materiais alternativos
 
Introdução à Visualização de Dados (2015)
Introdução à Visualização de Dados (2015)Introdução à Visualização de Dados (2015)
Introdução à Visualização de Dados (2015)
 
API de segurança do Java EE 8
API de segurança do Java EE 8API de segurança do Java EE 8
API de segurança do Java EE 8
 
Java 9, 10, 11
Java 9, 10, 11Java 9, 10, 11
Java 9, 10, 11
 
Curso de Java Persistence API (JPA) (Java EE 7)
Curso de Java Persistence API (JPA) (Java EE 7)Curso de Java Persistence API (JPA) (Java EE 7)
Curso de Java Persistence API (JPA) (Java EE 7)
 
Curso de Enterprise JavaBeans (EJB) (JavaEE 7)
Curso de Enterprise JavaBeans (EJB) (JavaEE 7)Curso de Enterprise JavaBeans (EJB) (JavaEE 7)
Curso de Enterprise JavaBeans (EJB) (JavaEE 7)
 
Introdução a JPA (2010)
Introdução a JPA (2010)Introdução a JPA (2010)
Introdução a JPA (2010)
 
Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)
Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)
Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)
 
Minicurso de Segurança em Java EE 7
Minicurso de Segurança em Java EE 7Minicurso de Segurança em Java EE 7
Minicurso de Segurança em Java EE 7
 
Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)
 
Threads 05: Travas de Exclusão Mútua
Threads 05: Travas de Exclusão MútuaThreads 05: Travas de Exclusão Mútua
Threads 05: Travas de Exclusão Mútua
 
Reconstruction of Pterosaurs using XPS
Reconstruction of Pterosaurs using XPSReconstruction of Pterosaurs using XPS
Reconstruction of Pterosaurs using XPS
 
A arquitetura modular do Java 9
A arquitetura modular do Java 9A arquitetura modular do Java 9
A arquitetura modular do Java 9
 
15 padrões de mensageria para integração de sistemas
15 padrões de mensageria para integração de sistemas15 padrões de mensageria para integração de sistemas
15 padrões de mensageria para integração de sistemas
 

Threads 10: CompletableFuture

  • 2. 1. Criação e controle de threads 2. Acesso exclusivo e comunicação entre threads 3. Ciclo de vida, aplicações e boas práticas 4. Variáveis atômicas 5. Travas 6. Coleções 7. Sincronizadores 8. Executores e Futures 9. Paralelismo 10. CompletableFuture THREADSCONCORRÊNCIAE PARALELISMOEMJAVA
  • 3. APICompletableFuture • API de execução assíncrona, funcional, baseada em fluxos de dados reativos introduzida no Java 8 • Consiste da interface CompletionStage e sua implementação: a classe CompletableFuture. • Possui mais de 70 métodos. • Métodos recebem interfaces funcionais e retornam CompletionStage (podem ser concatenados) • Programação similar a API de streams (mas usa push, em vez de pull)
  • 4. CompletionStage CompletableFuture<V> CompletionStage<V>Future<V> • Um CompletableFuture é um Future e também um CompletionStage: interface que representa uma computação possivelmente assíncrona • Um CompletableFuture é corrente de CompletionStages concatenados. • Cada CompletionStage executa uma etapa da tarefa. Cada etapa é executada quando a anterior termina, podendo usar seu resultado como entrada. CompletionStage CompletionStage CompletionStage
  • 5. CompletionStage • O primeiro elemento da corrente deve ser uma tarefa descrita pela interface funcional Runnable ou Supplier<T>. • Os estágios seguintes podem conter tarefas descritas pelas seguintes interfaces funcionais: • Consumer<T> (se não retornam valor) • Function<T,R> (se recebem valor e retornam outro) • Runnable (se não recebem nem passam valor adiante)
  • 6. Concatenaçãodeestágios CompletableFuture supplyAsync () -> event.get() CompletionStage thenApply x -> x * x CompletionStage thenAccept x -> System.out.println(x) CompletionStage thenRun () -> System.out.println("Done!") triggers triggers triggers • A execução de um estágio é disparada pela conclusão de um estágio anterior • Também pode esperar dois estágios ou um dentre dois estágios anteriores • Também é possível combinar resultados. Um evento pode completar um CompletableFuture chamando complete(valor)
  • 7. ComocriarumCompletableFuture • Usando o construtor default CompletableFuture<Integer> trigger = new CompletableFuture<>(); • CompletableFuture pode ser completado explicitamente usando complete(valor) ou completeAsync(Supplier) trigger.complete(5); • Um callback (esperando no get()) que executará depois do complete() new Thread(() -> { try { System.out.println("Resultado da tarefa: " + trigger.get()); } catch (InterruptedException | ExecutionException e) { ... } }).start();
  • 8. ComocriarumCompletableFuture • Usando métodos de fábrica e uma tarefa Runnable ou Supplier<V> • CompletableFuture.runAsync( Runnable tarefa) • CompletableFuture.supplyAsync( Supplier<T> tarefa) CompletableFuture<Void> cf1 = CompletableFuture.runAsync(() -> { for (int i = 0; i < 1_000_000_000; i++) if (i % 100_000_000 == 0) System.out.print("2"); }); CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> { StringBuilder builder = new StringBuilder(); for (int i = 0; i < 1_000_000_000; i++) if (i % 100_000_000 == 0) builder.append((char)(new Random().nextInt(26) + 'A')); return builder.toString(); });
  • 9. Estágiosiniciais () void R res Runnable «interface» void run() Supplier<R> «interface» R get() CompletionStage runAsync () -> void CompletionStage supplyAsync () -> r ()
  • 10. thenRun • Recebe interface funcional Runnable
 run() • Tarefas podem não recebem resultado e não produzem • Um estágio thenRun pode ser usado para callbacks que não dependem de valores de tarefas anteriores CompletableFuture.runAsync(() -> { for (int i = 0; i < 1_000_000_000; i++) if (i % 100_000_000 == 0) System.out.print("2"); }).thenRun(() -> System.out.println("DONE"));
  • 11. thenAccept • Recebe interface funcional Consumer<T>
 accept(T valor) • Tarefas podem receber um resultado (mas não produzem) • Um estágio thenAccept pode ser usado no final de uma cadeia CompletableFuture.supplyAsync(() -> { StringBuilder builder = new StringBuilder(); for (int i = 0; i < 1_000_000_000; i++) if (i % 100_000_000 == 0) builder.append((char)(new Random().nextInt(26) + 'A')); return builder.toString(); }).thenAccept(result -> System.out.println("Result is: " + result));
  • 12. thenApply TagOperations to = new TagOperations(); CompletableFuture.supplyAsync(() -> "text") .thenApply(s -> to.tag("p", s)) .thenApply(s -> s.concat("n")) .thenApply(s -> "n".concat(s)) .thenApply(s -> to.tag("div", s)) .thenAccept(s -> 
 System.out.println("Result:n" + s)); class TagOperations { String tag(String tagName, 
 String contents) {...} String unTag(String taggedText) {...} } • Recebe interface funcional Function<T,R>
 R apply(T valor) • Tarefas podem receber um resultado e produzir outro. • Vários estágios thenApply podem ser concatenados
  • 13. Estágiosintermediários () void T val void R res T val Runnable «interface» void run() Consumer<T> «interface» void accept(T val) Function<T,R> «interface» R apply(T val) CompletionStage thenRun () -> void CompletionStage thenAccept t -> void CompletionStage thenApply t -> r
  • 14. Estágiossíncronos • Cada estágio é executado no mesmo thread do estágio anterior, exceto se o método terminar em Async • Um estágio inicia apenas quando o estágio anterior termina (isto vale para estágios comuns e Async). • Se o estágio anterior produzir um resultado, o valor poderá ser usado pelo estágio seguinte main future future.join() forkjoin-pool thread-1 complete() complete() complete() complete() complete() thenAccept supplyAsync thenApply thenApply thenApply
  • 15. main future future.join() forkjoin-pool thread-1 forkjoin-pool thread-2 forkjoin-pool thread-3 complete() complete() complete() complete() complete() thenAccept supplyAsync thenApply thenApplyAsync thenApplyAsync Estágios Async • Se o método terminar em Async, o a tarefa é executada em novo thread • Mesmo em threads diferentes, um estágio seguinte só inicia quando o anterior é completado
  • 17. EscolhadoExecutorService • Os métodos Async permitem a escolha do serviço de execução (ExecutorService) que será usado pela tarefa ExecutorService executor = Executors.newSingleThreadExecutor(); CompletableFuture.supplyAsync(() -> loadFile("dictionary.csv")) .thenApply(data -> csvParser.parse(data)) .thenApply(data -> dataVizGenerator.lineChart(data)) .thenAcceptAsync(chart -> workspace.display(chart), executor); main thread fork-join-pool thread executor thread
  • 18. Exceções • Se um CompletionStage provocar uma exceção, ela será encapsulada dentro de uma CompletionException • A exceção é propagada pelos CompletionStages que vierem depois. • isCompletedExceptionally() retornará true • Se get() for chamado será lançada uma ExecutionException
  • 19. exceptionally • Funciona como bloco catch • Recebe Function<Throwable,T> • Pode substituir exceção por um valor válido CompletableFuture.supplyAsync(()->1/0) .exceptionally(e->0) .thenAccept(n->System.out::println));
  • 20. handle • Recebe BiFunction<T,Throwable, R> • Etapa completa normalmente e repassa resultado adiante. • Se houver exceção, resultado é null, mas exceção poderá ser utilizada. • Se a operação completar normalmente, a exceção será null. CompletableFuture.supplyAsync(()->1/0) .handle((data, error) -> { if(error != null) { return 0; } else return data; }) .thenAcceptAsync(s -> System.out.println("Result:" + s));
  • 21. whenComplete • Recebe um BiConsumer<T,Throwable> • Não tem como tratar a exceção (alterar o valor que é passado adiante) CompletableFuture.supplyAsync(()->1/0) .whenComplete((data, error) -> { if(error != null) { System.out.println("Error: " + error); } }) .exceptionally(e -> 0) .thenAccept(n->System.out::println));
  • 22. Estágiosquecapturamexceções void R r BiConsumer<T,U> «interface» void accept(T val,Throwable e) BiFunction<T,Throwable,R> «interface» R apply(T val,Throwable e) CompletionStage exceptionally e -> r CompletionStage whenComplete (t, e) -> void CompletionStage handle (t, e) -> r T val Throwable eThrowable e Function<Throwable,R> «interface» R apply(Throwable e) R r T val Throwable e
  • 23. CompletionException • Exceções são encapsuladas em CompletionException (podem ser extraídas usando getCause()) • Nas expressões dos métodos exceptionally() e handle() a exceção é automaticamente desempacotada java.util.concurrent.CompletionException getCause()java.io.IOException
  • 24. Desempacotamentoautomático java.io.IOException CompletionStage thenApply out -> out.println("text") CompletionStage exceptionally e -> System.out.println(e) CompletionStage thenApply out -> out.println("text") CompletionStage handle (d,e) -> System.out.println(e) java.io.IOException java.io.IOException java.io.IOException CompletionStage thenApply out -> out.println("text") CompletionStage whenComplete (d,e) -> System.out.println(e) java.io.IOException j.u.c.CompletionException • IOException provocada em um estágio e automaticamente desempacotada em exceptionally() e handle(), mas não em whenComplete()
  • 25. CombinaçãoAND • Estágios que esperam que dois estágios anteriores completem • runAfterBoth() • thenAcceptBoth() • thenCombine() CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello"); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World"); future1.runAfterBoth(future2, ()-> System.out.println("future1 e future2 terminaram!")); future1.thenAcceptBoth(future2, (f1,f2)-> System.out.println("Result: " + f1 + " " + f2 + "!"))); CompletableFuture<Integer> future3 = future2.thenApply(s -> s.length()); CompletableFuture<Integer> future4 = future1.thenCombine(future3, (f1,f3)-> f1.length() + f3);
  • 26. CombinaçãoAND () void void R res Runnable «interface» void run() BiConsumer<T,U> «interface» void accept(T val1, U val2) BiFunction<T,U,R> «interface» R apply(T val1, U val2) CompletionStage runAfterBoth () -> void CompletionStage thenAcceptBoth (t, u) -> void CompletionStage thenCombine (t, u) -> r T val1 U val2 T val1 U val2
  • 27. CombinaçãoOR • Estágios que esperam que um, dentre dois estágios anteriores, complete • runAfterEither() • acceptEither() • applyToEither() future1.runAfterEither(future2, () -> System.out.println("Terminou future1 ou future2")); future1.acceptEither(future2, s -> System.out.println(s)); // imprime “Hello” ou “World” future1.applyToEither(future2, s -> s.toUpperCase()) .thenAccept(s -> System.out.println(s)); // imprime “HELLO” ou “WORLD”
  • 28. CombinaçãoOR () void void R res T val CompletionStage runEither () -> void CompletionStage acceptEither t -> void CompletionStage applyToEither t -> r T val Runnable «interface» void run() Consumer<T> «interface» void accept(T val) Function<T,R> «interface» R apply(T val)
  • 29. Composiçaodeestágios • thenCompose() • Análogo ao método flatMap() de Stream CompletionStage thenCompose t -> stage CompletionStage stage T val Function<T,CompletionStage> «interface» CompletionStage apply(T val) CompletableFuture<String> stage1 = new CompletableFuture<>(); CompletableFuture<String> stage2 = CompletableFuture.supplyAsync(() -> "World"); CompletableFuture<CompletableFuture<String>> stage3 = stage1.thenApply(s1 -> stage2.thenApply(s2 -> s1 + s2.toUpperCase())); stage3.thenAccept(cf -> System.out.println("S3: " + cf.join())); CompletableFuture<String> stage4 = stage1.thenCompose(s1 -> stage2.thenApply(s2 -> s1 + s2.toUpperCase())); stage4.thenAccept(s -> System.out.println("S4: " + s)); stage1.complete("Hello, "); stage1.join();
  • 30. CombinaçãoeseleçãodeCompletableFutures • anyOf() retorna CompletableFuture que é completado assim que um dos CompletableFutures da lista completar • allOf() retorna CompletableFuture que é completado quando todos os CompletableFutures da lista completarem. List<CompletableFuture<?>> fs = List.of(f1, f2, f3, f4); CompletableFuture<?>[] array = fs.toArray(new CompletableFuture[fs.size()]); CompletableFuture<List<?>>> resultados = CompletableFuture.allOf(array) .thenApply(v -> fs.stream().map(f -> f.join()) .collect(Collectors.toList())); CompletableFuture<?> anyFuture = CompletableFuture.anyOf(array));
  • 31. Outrosmétodos • completedFuture(valor) • Retorna um CompletableFuture já completo e com o valor passado como argumento. Útil para a construção de testes. • completeExceptionally(throwable) • Chamadas a get(), join() e similares lançam exceção passada como argumento, se CompletableFuture ainda não tiver completado a tarefa • obtrudeValue(valor) e obtrudeException(throwable) • Forçam retorno de valor diferente para get(), join() ou lançamento de exceção diferente, independente da tarefa ter sido completada ou não
  • 32. THREADSCONCORRÊNCIAE PARALELISMOEMJAVA Helder da Rocha (helder@summa.com.br) github.com/helderdarocha/java8-course/ /java/concurrency/ Maio 2015