SlideShare una empresa de Scribd logo
1 de 35
Descargar para leer sin conexión
Working Effectively
With Asynchronous Code
Eduardo Sánchez Contreras
Madrid JUG
¿Quién es éste?
Eduardo Sánchez
@edusanchezcon
Consultor tecnológico en Autentia
github.com/EduSanchezCon
¿Qué vamos a ver?
1. Introducción y Motivaciones
2. Distintas implementaciones
3. Problemas en aplicaciones reales
4. Preguntas, ruegos, amenazas…
El secreto de esta vida
está en hacer cosas
— Javier Prieto
La CPU pasa mucho tiempo esperando
Lectura de ficheros
BBDD
APIs externas
O podría estar más ocupada
Programación asíncrona,
ese gran desconocido
Parallel streams
Rx
java.util.concurrent
android
AJAXRunnable
large_process.sh &
iOS
?
Asynchronous programming is different
synchronous
synchronous
synchronous
synchronous
asynchronous
asynchronous
asynchronous
asynchronous
Se pierde la secuencialidad
Asynchronous programming is different
Asynchronous programming is different
No podemos asumir que dentro de N líneas
de código dispondremos del resultado de
una llamada asíncrona
A B C
Cuando termine B
async
Programación declarativa
¿Qué nos da? Potencia
Distintos cores para tareas costosas
Sistema de hilos para esperas largas
Más propenso a fallos
Hilos colgados
Sobrecarga de memoria
Difícil de depurar
¿Qué conlleva? Complejidad
No nos flipemos
Hay distintas implementaciones
Hay distintas implementaciones
Callbacks
$.get(
"https://api.coinmarketcap.com/v1/ticker/?limit=10",
// Callback
function(data) {
$("#result").html(
data.map(c => c.name).join(“<br>")
);
}
);
Hay distintas implementaciones
public get<T>(endpoint: string): Observable<T> {
return this.httpClient.get( endpoint );
}
...
get<Coin[]>("https://api.coinmarketcap.com/v1/ticker/")
.subscribe(
coin => console.log(coin.name)
);
Callbacks Observers
Hay distintas implementaciones
Callbacks Futures
ExecutorService executor = Executors.newFixedThreadPool(3);
final GetCourseInfo getCourseInfo = new GetCourseInfo();
List<Future<Course>> futures = new ArrayList<>();
for (int i=1; i<=3; i++){
final int id = i;
Future<Course> future = executor.submit(
() -> getCourseInfo.apply(id).get()
);
futures.add(future);
}
for (Future<Course> future : futures){
try {
System.out.println(future.get());
} catch (InterruptedException | ExecutionException e) {}
}
Observers
Hay distintas implementaciones
val p = Promise[Optional[Course]]()
val f = p.future
val producer = Future {
val r = new GetCourseInfo() apply (1)
p success r
}
Future {
f onComplete {
case Success(optional) =>
println(JsonSerializer.PRETTY.serialize(optional.get()))
}
}
Callbacks Futures PromisesObservers
I’m Future,
CompletableFuture
Future
get
cancel isDone
isCancelled
CompletionStage
thenAccept
thenApply
thenComplete
thenCombine
acceptEither
combineEither
…
CompletableFuture
complete
completeExceptionally
join
getNow
static allOf
static anyOf
static runAsync
static supplyAsync
static completedFuture
¿Qué podemos hacer con los futuros?
¿Qué podemos hacer con los futuros?
Crearlos
CompletableFuture<Void> voidFuture = CompletableFuture.runAsync(
() -> System.out.println("Soy asíncrono!!"));
CompletableFuture<String> futureValue = CompletableFuture.supplyAsync(
() -> "En el futuro devolveré esta cadena");
CompletableFuture<String> fakeFuture =
CompletableFuture.completedFuture("Esto es útil en Tests");
¿Qué podemos hacer con los futuros?
Obtener su valor de manera síncrona
try {
String value = futureValue.get(5L, TimeUnit.SECONDS);
} catch (InterruptedException|ExecutionException|TimeoutException e){ }
String value2 = futureValue2.join();
String value3 = futureValue3.getNow("");
¡OJO!
¿Qué podemos hacer con los futuros?
Tratar su resultado de manera asíncrona
future.thenApply( String::toUpperCase );
future.thenAccept( System.out::println );
future.thenRun( () -> System.out.println("La tarea terminó") );
future.handle((v, ex) -> {
if (ex != null) return null;
else return v;
} );
future.whenComplete((v, ex) -> {
if (v != null) System.out.println(v);
} );
¿Qué podemos hacer con los futuros?
Interactuar con otro futuro
// Una llamada depende de la otra
CompletableFuture<Integer> future = duplicateAsync(3)
.thenCompose( n -> duplicateAsync(n));
//Combinar dos llamadas en paralelo
future1 = CompletableFuture.supplyAsync( () -> "MOLA");
future2 = CompletableFuture.supplyAsync( () -> "MAZO");
CompletableFuture<String> combine = future1.thenCombine(future2,
(s1, s2) -> s1 + " " + s2);
¿Qué podemos hacer con los futuros?
Interactuar con muchos futuros
// Se queda con el primer futuro que se resuelva
CompletableFuture<Object> fastest = CompletableFuture.anyOf(futuresArray);
fastestFuture.whenComplete((course, th) -> {
if(th == null) {
System.out.println( course);
}
});
// Espera hasta resolver todos los futuros
CompletableFuture<Void> all = CompletableFuture.allOf(arrayOfFutures);
all.thenAccept(v -> {
Arrays.stream(arrayOfFutures)
.map(CompletableFuture::join)
.forEach(System.out::println);
});
¿Qué podemos hacer con los futuros?
Completarlos (promesas)
public class SingleEventNotifier{
final CompletableFuture<EventInfo> futureEvent;
public SingleEventNotifier(EventEmitter emitter) {
this.futureEvent = new CompletableFuture<>();
emitter.subscribe(this);
}
public CompletableFuture<EventInfo> ask(){
return futureEvent;
}
public void onEventReceived(EventInfo event){
futureEvent.complete(event);
}
}
Nadie golpea más fuerte
que la vida
— Rocky Balboa
“
”
Manejando los hilos
Demo
Nunca uses el commonPool
para tareas bloqueantes
Tampoco crees un
Executor en cada llamada
Listas de futuros heterogéneos
Dem
o
Conclusiones
La programación asíncrona es potente
Usémosla con criterio
Mucho cuidado con los threadPools
SOLID es tu amigo
Trabajando-eficazmente-con-código-asíncrono
Trabajando-eficazmente-con-código-asíncrono

Más contenido relacionado

Similar a Trabajando-eficazmente-con-código-asíncrono

Sockets en c
Sockets en cSockets en c
Sockets en cMaShYy
 
Compilador Usando Jflex y Cup
Compilador Usando Jflex y CupCompilador Usando Jflex y Cup
Compilador Usando Jflex y Cupditopo
 
Lenguaje de programacion java, conceptos
Lenguaje de programacion java, conceptosLenguaje de programacion java, conceptos
Lenguaje de programacion java, conceptosmellcv
 
Javascript Módulo 5 - javascript sentencia, expresión, variable, función - Un...
Javascript Módulo 5 - javascript sentencia, expresión, variable, función - Un...Javascript Módulo 5 - javascript sentencia, expresión, variable, función - Un...
Javascript Módulo 5 - javascript sentencia, expresión, variable, función - Un...David Zapateria Besteiro
 
OOP - Lab 1 - Variables y Asignacion.pdf
OOP - Lab 1 - Variables y Asignacion.pdfOOP - Lab 1 - Variables y Asignacion.pdf
OOP - Lab 1 - Variables y Asignacion.pdfMariaJose48908
 
Programación Reactiva en Android
Programación Reactiva en AndroidProgramación Reactiva en Android
Programación Reactiva en AndroidDroidcon Spain
 
Porqué Cervantes programaba mejor que tú
Porqué Cervantes programaba mejor que túPorqué Cervantes programaba mejor que tú
Porqué Cervantes programaba mejor que túAgile Spain
 
Por qué Cervantes programaba mejor que tú
Por qué Cervantes programaba mejor que túPor qué Cervantes programaba mejor que tú
Por qué Cervantes programaba mejor que túJavier Acero
 
Por que java
Por que javaPor que java
Por que javareivax
 
Computación evolutiva no tradicional
Computación evolutiva no tradicionalComputación evolutiva no tradicional
Computación evolutiva no tradicionalJuan J. Merelo
 
Introducción a la Programación con Java
Introducción a la Programación con JavaIntroducción a la Programación con Java
Introducción a la Programación con Javaflekoso
 
Proyecto de compiladores Sentencia While con Java CUP y JFLEX
Proyecto de compiladores Sentencia While con Java CUP y JFLEXProyecto de compiladores Sentencia While con Java CUP y JFLEX
Proyecto de compiladores Sentencia While con Java CUP y JFLEXIvan Luis Jimenez
 

Similar a Trabajando-eficazmente-con-código-asíncrono (20)

Sockets en c
Sockets en cSockets en c
Sockets en c
 
Informe karen jacome
Informe karen jacomeInforme karen jacome
Informe karen jacome
 
Compilador Usando Jflex y Cup
Compilador Usando Jflex y CupCompilador Usando Jflex y Cup
Compilador Usando Jflex y Cup
 
Lenguaje de programacion java, conceptos
Lenguaje de programacion java, conceptosLenguaje de programacion java, conceptos
Lenguaje de programacion java, conceptos
 
Javascript Módulo 5 - javascript sentencia, expresión, variable, función - Un...
Javascript Módulo 5 - javascript sentencia, expresión, variable, función - Un...Javascript Módulo 5 - javascript sentencia, expresión, variable, función - Un...
Javascript Módulo 5 - javascript sentencia, expresión, variable, función - Un...
 
Introducción a java
Introducción a javaIntroducción a java
Introducción a java
 
Practica cliente servidor java
Practica cliente servidor javaPractica cliente servidor java
Practica cliente servidor java
 
OOP - Lab 1 - Variables y Asignacion.pdf
OOP - Lab 1 - Variables y Asignacion.pdfOOP - Lab 1 - Variables y Asignacion.pdf
OOP - Lab 1 - Variables y Asignacion.pdf
 
Programación Reactiva en Android
Programación Reactiva en AndroidProgramación Reactiva en Android
Programación Reactiva en Android
 
Boletin1
Boletin1Boletin1
Boletin1
 
Ejercicios3
Ejercicios3Ejercicios3
Ejercicios3
 
Porqué Cervantes programaba mejor que tú
Porqué Cervantes programaba mejor que túPorqué Cervantes programaba mejor que tú
Porqué Cervantes programaba mejor que tú
 
Por qué Cervantes programaba mejor que tú
Por qué Cervantes programaba mejor que túPor qué Cervantes programaba mejor que tú
Por qué Cervantes programaba mejor que tú
 
Por que java
Por que javaPor que java
Por que java
 
Computación evolutiva no tradicional
Computación evolutiva no tradicionalComputación evolutiva no tradicional
Computación evolutiva no tradicional
 
Introducción a la Programación con Java
Introducción a la Programación con JavaIntroducción a la Programación con Java
Introducción a la Programación con Java
 
Fund Java
Fund JavaFund Java
Fund Java
 
Proyecto de compiladores Sentencia While con Java CUP y JFLEX
Proyecto de compiladores Sentencia While con Java CUP y JFLEXProyecto de compiladores Sentencia While con Java CUP y JFLEX
Proyecto de compiladores Sentencia While con Java CUP y JFLEX
 
Concurrencia en Java
Concurrencia en Java Concurrencia en Java
Concurrencia en Java
 
Presentación 09 Cajas blanca
Presentación 09 Cajas blancaPresentación 09 Cajas blanca
Presentación 09 Cajas blanca
 

Trabajando-eficazmente-con-código-asíncrono

  • 1. Working Effectively With Asynchronous Code Eduardo Sánchez Contreras Madrid JUG
  • 2. ¿Quién es éste? Eduardo Sánchez @edusanchezcon Consultor tecnológico en Autentia github.com/EduSanchezCon
  • 3. ¿Qué vamos a ver? 1. Introducción y Motivaciones 2. Distintas implementaciones 3. Problemas en aplicaciones reales 4. Preguntas, ruegos, amenazas…
  • 4. El secreto de esta vida está en hacer cosas — Javier Prieto
  • 5. La CPU pasa mucho tiempo esperando Lectura de ficheros BBDD APIs externas
  • 6. O podría estar más ocupada
  • 7. Programación asíncrona, ese gran desconocido Parallel streams Rx java.util.concurrent android AJAXRunnable large_process.sh & iOS ?
  • 10. Asynchronous programming is different No podemos asumir que dentro de N líneas de código dispondremos del resultado de una llamada asíncrona A B C Cuando termine B async Programación declarativa
  • 11. ¿Qué nos da? Potencia Distintos cores para tareas costosas Sistema de hilos para esperas largas
  • 12. Más propenso a fallos Hilos colgados Sobrecarga de memoria Difícil de depurar ¿Qué conlleva? Complejidad
  • 14.
  • 16. Hay distintas implementaciones Callbacks $.get( "https://api.coinmarketcap.com/v1/ticker/?limit=10", // Callback function(data) { $("#result").html( data.map(c => c.name).join(“<br>") ); } );
  • 17. Hay distintas implementaciones public get<T>(endpoint: string): Observable<T> { return this.httpClient.get( endpoint ); } ... get<Coin[]>("https://api.coinmarketcap.com/v1/ticker/") .subscribe( coin => console.log(coin.name) ); Callbacks Observers
  • 18. Hay distintas implementaciones Callbacks Futures ExecutorService executor = Executors.newFixedThreadPool(3); final GetCourseInfo getCourseInfo = new GetCourseInfo(); List<Future<Course>> futures = new ArrayList<>(); for (int i=1; i<=3; i++){ final int id = i; Future<Course> future = executor.submit( () -> getCourseInfo.apply(id).get() ); futures.add(future); } for (Future<Course> future : futures){ try { System.out.println(future.get()); } catch (InterruptedException | ExecutionException e) {} } Observers
  • 19. Hay distintas implementaciones val p = Promise[Optional[Course]]() val f = p.future val producer = Future { val r = new GetCourseInfo() apply (1) p success r } Future { f onComplete { case Success(optional) => println(JsonSerializer.PRETTY.serialize(optional.get())) } } Callbacks Futures PromisesObservers
  • 22. ¿Qué podemos hacer con los futuros?
  • 23. ¿Qué podemos hacer con los futuros? Crearlos CompletableFuture<Void> voidFuture = CompletableFuture.runAsync( () -> System.out.println("Soy asíncrono!!")); CompletableFuture<String> futureValue = CompletableFuture.supplyAsync( () -> "En el futuro devolveré esta cadena"); CompletableFuture<String> fakeFuture = CompletableFuture.completedFuture("Esto es útil en Tests");
  • 24. ¿Qué podemos hacer con los futuros? Obtener su valor de manera síncrona try { String value = futureValue.get(5L, TimeUnit.SECONDS); } catch (InterruptedException|ExecutionException|TimeoutException e){ } String value2 = futureValue2.join(); String value3 = futureValue3.getNow(""); ¡OJO!
  • 25. ¿Qué podemos hacer con los futuros? Tratar su resultado de manera asíncrona future.thenApply( String::toUpperCase ); future.thenAccept( System.out::println ); future.thenRun( () -> System.out.println("La tarea terminó") ); future.handle((v, ex) -> { if (ex != null) return null; else return v; } ); future.whenComplete((v, ex) -> { if (v != null) System.out.println(v); } );
  • 26. ¿Qué podemos hacer con los futuros? Interactuar con otro futuro // Una llamada depende de la otra CompletableFuture<Integer> future = duplicateAsync(3) .thenCompose( n -> duplicateAsync(n)); //Combinar dos llamadas en paralelo future1 = CompletableFuture.supplyAsync( () -> "MOLA"); future2 = CompletableFuture.supplyAsync( () -> "MAZO"); CompletableFuture<String> combine = future1.thenCombine(future2, (s1, s2) -> s1 + " " + s2);
  • 27. ¿Qué podemos hacer con los futuros? Interactuar con muchos futuros // Se queda con el primer futuro que se resuelva CompletableFuture<Object> fastest = CompletableFuture.anyOf(futuresArray); fastestFuture.whenComplete((course, th) -> { if(th == null) { System.out.println( course); } }); // Espera hasta resolver todos los futuros CompletableFuture<Void> all = CompletableFuture.allOf(arrayOfFutures); all.thenAccept(v -> { Arrays.stream(arrayOfFutures) .map(CompletableFuture::join) .forEach(System.out::println); });
  • 28. ¿Qué podemos hacer con los futuros? Completarlos (promesas) public class SingleEventNotifier{ final CompletableFuture<EventInfo> futureEvent; public SingleEventNotifier(EventEmitter emitter) { this.futureEvent = new CompletableFuture<>(); emitter.subscribe(this); } public CompletableFuture<EventInfo> ask(){ return futureEvent; } public void onEventReceived(EventInfo event){ futureEvent.complete(event); } }
  • 29. Nadie golpea más fuerte que la vida — Rocky Balboa “ ”
  • 31. Nunca uses el commonPool para tareas bloqueantes Tampoco crees un Executor en cada llamada
  • 32. Listas de futuros heterogéneos Dem o
  • 33. Conclusiones La programación asíncrona es potente Usémosla con criterio Mucho cuidado con los threadPools SOLID es tu amigo