SlideShare una empresa de Scribd logo
1 de 65
Descargar para leer sin conexión
TO BE CONTINUED
Multithreading with Project
Loom and Kotlin's Coroutines
ARTUR SKOWROŃSKI
VIRTUSLAB
WON’T TEACH YOU
COROUTINES.
SYNCHRONOUS
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
SYNCHRONOUS
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
SYNCHRONOUS
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
SYNCHRONOUS
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
SYNCHRONOUS
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
CALLBACKS
fun main(args: Array<String>) {
getLocationsNearCoordinates("SW8 5YY, UK")
.success {location ->
val category = location.classification.category
if (category == "Store") {
getStoreDetails(location.id)
.success { locationWrapper ->
val openingHours = locationWrapper
.openingHours
.first()
.standardOpeningHours
println("Store Opening Hours: $openingHours")
}
}
if (category == "Office") {
payOfficeRent(location.id)
.success {
println("Invoice paid")
}
}
}
}
CALLBACKS
fun main(args: Array<String>) {
getLocationsNearCoordinates("SW8 5YY, UK")
.success {location ->
val category = location.classification.category
if (category == "Store") {
getStoreDetails(location.id)
.success { locationWrapper ->
val openingHours = locationWrapper
.openingHours
.first()
.standardOpeningHours
println("Store Opening Hours: $openingHours")
}
}
if (category == "Office") {
payOfficeRent(location.id)
.success {
println("Invoice paid")
}
}
}
}
CALLBACKS
fun main(args: Array<String>) {
getLocationsNearCoordinates("SW8 5YY, UK")
.success {location ->
val category = location.classification.category
if (category == "Store") {
getStoreDetails(location.id)
.success { locationWrapper ->
val openingHours = locationWrapper
.openingHours
.first()
.standardOpeningHours
println("Store Opening Hours: $openingHours")
}
}
if (category == "Office") {
payOfficeRent(location.id)
.success {
println("Invoice paid")
}
}
}
}
CALLBACKS
fun main(args: Array<String>) {
getLocationsNearCoordinates("SW8 5YY, UK")
.success {location ->
val category = location.classification.category
if (category == "Store") {
getStoreDetails(location.id)
.success { locationWrapper ->
val openingHours = locationWrapper
.openingHours
.first()
.standardOpeningHours
println("Store Opening Hours: $openingHours")
}
}
if (category == "Office") {
payOfficeRent(location.id)
.success {
println("Invoice paid")
}
}
}
}
CALLBACKS
fun main(args: Array<String>) {
getLocationsNearCoordinates("SW8 5YY, UK")
.success {location ->
val category = location.classification.category
if (category == "Store") {
getStoreDetails(location.id)
.success { locationWrapper ->
val openingHours = locationWrapper
.openingHours
.first()
.standardOpeningHours
println("Store Opening Hours: $openingHours")
}
}
if (category == "Office") {
payOfficeRent(location.id)
.success {
println("Invoice paid")
}
}
}
}
CALLBACKS
fun main(args: Array<String>) {
getLocationsNearCoordinates("SW8 5YY, UK")
.success {location ->
val category = location.classification.category
if (category == "Store") {
getStoreDetails(location.id)
.success { locationWrapper ->
val openingHours = locationWrapper
.openingHours
.first()
.standardOpeningHours
println("Store Opening Hours: $openingHours")
}
}
if (category == "Office") {
payOfficeRent(location.id)
.success {
println("Invoice paid")
}
}
}
}
PROMISESRX
BRANCHING IS HARD
fun combineAsync(name1: String, name2: String): CompletableFuture<Image>{
val future1 = CompletableFuture.supplyAsync(name1-> ...)
val future2 = CompletableFuture.supplyAsync(name2-> ...)
return future1.thenCombine(future2){i1,i2 -> ...}
}
EXCEPTION HANDLING
IS HARD
OVERALL IT’S HARD…
IMPERATIVE
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
COROUTINES
Współprogram
1958
1963
NATIVE SUPPORT
NATIVE?
IMPERATIVE
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
COROUTINE
fun main() {
GlobalScope.launch {
val location = getLocationsNearKnownPostcode().first()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
runBlocking {
delay(2000L)
}
}
suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK")
}
suspend fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours.first().standardOpeningHours
}
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
COROUTINE
fun main() {
GlobalScope.launch {
val location = getLocationsNearKnownPostcode().first()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
runBlocking {
delay(2000L)
}
}
suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK")
}
suspend fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours.first().standardOpeningHours
}
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
COROUTINE
fun main() {
GlobalScope.launch {
val location = getLocationsNearKnownPostcode().first()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
runBlocking {
delay(2000L)
}
}
suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK")
}
suspend fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours.first().standardOpeningHours
}
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
COROUTINE
fun main() {
GlobalScope.launch {
val location = getLocationsNearKnownPostcode().first()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
runBlocking {
delay(2000L)
}
}
suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK")
}
suspend fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours.first().standardOpeningHours
}
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
COROUTINE
fun main() {
GlobalScope.launch {
val location = getLocationsNearKnownPostcode().first()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
runBlocking {
delay(2000L)
}
}
suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK")
}
suspend fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours.first().standardOpeningHours
}
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
THREAD
BLOCKED
Function 1
Function 2
SUSPEND
Function 1
Function 2
THREAD
Suspension Point
SUSPEND
Coroutine 1
Function 2
getLocationsNearKnownPostcode getOpeningHours
Function 3
THREAD
CONTINUATIONS
DIRECT STYLE CODE
Action + Result and Continuation
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
ActionResult
Continuation
CONTINUATION PASSING STYLE
getLocationsNearKnownPostcode()
.success {location ->
val category = location.classification.category
}
Action
Result
CONTINUATION PASSING STYLE
getLocationsNearKnownPostcode()
.success {location ->
val category = location.classification.category
}
Action
Result
Fancy Name for Callback
Continuation
FROM KOTLIN FILE
suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK")
}
suspend fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours.first().standardOpeningHours
}
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
public final static getLocationsNearKnownPostcode(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@Lorg/jetbrains/annotations/Nullable;() // invisible
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
L0
LINENUMBER 33 L0
LDC "SW8 5YY, UK"
INVOKESTATIC TescoLocationAPIKt.getLocationsNearCoordinates (Ljava/lang/String;)Ljava/util/List;
ARETURN
L1
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x19
// signature (Ljava/lang/String;Lkotlin/coroutines/Continuation<Ljava/lang/Object;>;)Ljava/lang/Object;
// declaration: getOpeningHours(java.lang.String, kotlin.coroutines.Continuation<java.lang.Object>)
public final static getOpeningHours(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@Lorg/jetbrains/annotations/Nullable;() // invisible
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1
L0
LINENUMBER 37 L0
ALOAD 0
INVOKESTATIC TescoLocationAPIKt.getStoreDetails (Ljava/lang/String;)LLocationWrapper;
INVOKEVIRTUAL LocationWrapper.getOpeningHours ()[LLocationOpeningHours;
INVOKESTATIC kotlin/collections/ArraysKt.first ([Ljava/lang/Object;)Ljava/lang/Object;
CHECKCAST LocationOpeningHours
INVOKEVIRTUAL LocationOpeningHours.getStandardOpeningHours ()Ljava/util/HashMap;
ARETURN
L1
LOCALVARIABLE id Ljava/lang/String; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 2
// access flags 0x19
// signature (Ljava/lang/String;Lkotlin/coroutines/Continuation<Ljava/lang/Object;>;)Ljava/lang/Object;
// declaration: payInvoice(java.lang.String, kotlin.coroutines.Continuation<java.lang.Object>)
public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@Lorg/jetbrains/annotations/Nullable;() // invisible
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1
L0
LINENUMBER 41 L0
ALOAD 0
INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult;
ARETURN
L1
LOCALVARIABLE id Ljava/lang/String; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 2
JVM BYTECODE
TAKE A LOOK
public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@Lorg/jetbrains/annotations/Nullable;() // invisible
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1
L0
LINENUMBER 41 L0
ALOAD 0
INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult;
ARETURN
L1
LOCALVARIABLE id Ljava/lang/String; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 2
TAKE A LOOK
public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@Lorg/jetbrains/annotations/Nullable;() // invisible
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1
L0
LINENUMBER 41 L0
ALOAD 0
INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult;
ARETURN
L1
LOCALVARIABLE id Ljava/lang/String; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 2
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
TAKE A LOOK
public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@Lorg/jetbrains/annotations/Nullable;() // invisible
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1
L0
LINENUMBER 41 L0
ALOAD 0
INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult;
ARETURN
L1
LOCALVARIABLE id Ljava/lang/String; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 2
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
public interface Continuation<in T> {
public val context: CoroutineContext
public fun resumeWith(result: Result<T>)
}
TAKE A LOOK
public final static main()V
L0
LINENUMBER 13 L0
GETSTATIC kotlinx/coroutines/GlobalScope.INSTANCE : Lkotlinx/coroutines/GlobalScope;
CHECKCAST kotlinx/coroutines/CoroutineScope
ACONST_NULL
ACONST_NULL
NEW kotlinx/coroutines/guide/compose01/CoroutineCodeKt$main$1
DUP
ACONST_NULL
INVOKESPECIAL kotlinx/coroutines/guide/compose01/CoroutineCodeKt$main$1.<init> (Lkotlin/coroutines/
Continuation;)V
CHECKCAST kotlin/jvm/functions/Function2
ICONST_3
ACONST_NULL
INVOKESTATIC kotlinx/coroutines/BuildersKt.launch$default (Lkotlinx/coroutines/
CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/
functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
POP
L1
COROUTINE
Coroutine
Stack
Operation 1
Operation 2
Operation 3
SUSPEND FUNCTION
Operation 1
Operation 2
Operation 3
Operation 4
Operation 5
SUSPEND FUNCTION
Operation 4
Operation 5
State
Operation 1
Operation 2
Operation 3
PROJECT LOOM
KERNEL THREADS
PROCESSESOS
PROCESS
PROCESS
THREAD
THREAD
THREAD
THREAD
KERNEL SPACE THREADS
THREADS
CPU SHEDULER
THREAD
Instruction 1
Instruction 2
Instruction 3
Instruction 4
THREAD
Continuation
OS
CPU SHEDULER
THREAD
Instruction 1
Instruction 2
Instruction 3
Instruction 4
THREAD
USER/KERNEL SPACE BORDER
CPU SHEDULER JVM
CONTEXT SWITCH
PROJECT METROPOLIS
PROJECT VALHALLA
PROJECT AMBER
PROJECT PANAMA
PROJECT LOOM
THREAD
USER/KERNEL SPACE BORDER
CPU SCHEDULER JVM
FORKJOINSCHEDULER
THREAD
THREAD
THREAD
THREAD
USER/KERNEL SPACE BORDER
CPU SCHEDULER JVM
FORKJOINSCHEDULER
THREAD
Instruction 1
Instruction 2
Instruction 3
Instruction 4
Coroutines
public class Continuation implements Runnable {
public Continuation(ContinuationScope s, Runnable r)
public final void run()
public static void yield(ContinuationScope s)
public boolean isDone()
}
Thread Fiber
Strand
FIBER
Scheduler + Continuation
var scope = new ContinuationScope("scheduler");
private final Fiber<Void> execution;
execution.apply(() -> {
var location = getLocationsNearKnownPostcode.yield(scope);
var category = location.classification.category
if (category == "Store") {
var openingHours = getOpeningHours(location.id).yield(scope)
System.out.println("Store Opening Hours:"+ openingHours)
}
if (category == "Office")
payInvoice(location.id).yield()
println("Invoice paid")
}
});
NO MORE THREAD POOLS
Thread: ~1MB
Fiber: ~1KB
HTTP://DOCS.PARALLELUNIVERSE.CO/QUASAR/
LACK OF COMMON
ABSTRACTION
RESTRICTIONS
Lack of support for JNI
Cannot suspend under lock
Partial (emulated) support for
ThreadLocal
hg clone http://hg.openjdk.java.net/loom/loom
cd loom
hg update -r fibers
sh configure
make images
JAVA 11
DONE WHEN IT’S DONE
SOURCES
http://cr.openjdk.java.net/~rpressler/loom/Loom-
Proposal.html
https://www.youtube.com/watch?v=YrrUCSi72E8
KOTLINCONF 2017 - DEEP DIVE INTO COROUTINES
ON JVM BY ROMAN ELIZAROV
https://www.youtube.com/watch?v=vbGbXUjlRyQ
PROJECT LOOM: FIBERS AND CONTINUATIONS FOR
JAVA BY ALAN BATEMAN
PROJECT LOOM: FIBERS AND CONTINUATIONS FOR
THE JAVA VIRTUAL MACHINE
THANK YOU

Más contenido relacionado

La actualidad más candente

Web весна 2013 лекция 6
Web весна 2013 лекция 6Web весна 2013 лекция 6
Web весна 2013 лекция 6Technopark
 
Web осень 2012 лекция 6
Web осень 2012 лекция 6Web осень 2012 лекция 6
Web осень 2012 лекция 6Technopark
 
The Ring programming language version 1.7 book - Part 93 of 196
The Ring programming language version 1.7 book - Part 93 of 196The Ring programming language version 1.7 book - Part 93 of 196
The Ring programming language version 1.7 book - Part 93 of 196Mahmoud Samir Fayed
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresiMasters
 
The Ring programming language version 1.4 book - Part 21 of 30
The Ring programming language version 1.4 book - Part 21 of 30The Ring programming language version 1.4 book - Part 21 of 30
The Ring programming language version 1.4 book - Part 21 of 30Mahmoud Samir Fayed
 
Unbreakable: The Craft of Code
Unbreakable: The Craft of CodeUnbreakable: The Craft of Code
Unbreakable: The Craft of CodeJoe Morgan
 
The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 103 of 212
The Ring programming language version 1.10 book - Part 103 of 212The Ring programming language version 1.10 book - Part 103 of 212
The Ring programming language version 1.10 book - Part 103 of 212Mahmoud Samir Fayed
 
Sql
SqlSql
SqlJoao
 
Elixir -Tolerância a Falhas para Adultos - GDG Campinas
Elixir  -Tolerância a Falhas para Adultos - GDG CampinasElixir  -Tolerância a Falhas para Adultos - GDG Campinas
Elixir -Tolerância a Falhas para Adultos - GDG CampinasFabio Akita
 
ZIO actors by Mateusz Sokół Scalac
ZIO actors by Mateusz Sokół ScalacZIO actors by Mateusz Sokół Scalac
ZIO actors by Mateusz Sokół ScalacScalac
 
Nik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReactNik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReactOdessaJS Conf
 
The Ring programming language version 1.5.4 book - Part 77 of 185
The Ring programming language version 1.5.4 book - Part 77 of 185The Ring programming language version 1.5.4 book - Part 77 of 185
The Ring programming language version 1.5.4 book - Part 77 of 185Mahmoud Samir Fayed
 
Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIOJohn De Goes
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askAndrea Giuliano
 
Parse Everything With Elixir
Parse Everything With ElixirParse Everything With Elixir
Parse Everything With ElixirGabriele Lana
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubyJason Yeo Jie Shun
 
The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202Mahmoud Samir Fayed
 
Postgres rules
Postgres rulesPostgres rules
Postgres rulesgisborne
 

La actualidad más candente (20)

Web весна 2013 лекция 6
Web весна 2013 лекция 6Web весна 2013 лекция 6
Web весна 2013 лекция 6
 
Web осень 2012 лекция 6
Web осень 2012 лекция 6Web осень 2012 лекция 6
Web осень 2012 лекция 6
 
The Ring programming language version 1.7 book - Part 93 of 196
The Ring programming language version 1.7 book - Part 93 of 196The Ring programming language version 1.7 book - Part 93 of 196
The Ring programming language version 1.7 book - Part 93 of 196
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan Soares
 
The Ring programming language version 1.4 book - Part 21 of 30
The Ring programming language version 1.4 book - Part 21 of 30The Ring programming language version 1.4 book - Part 21 of 30
The Ring programming language version 1.4 book - Part 21 of 30
 
Unbreakable: The Craft of Code
Unbreakable: The Craft of CodeUnbreakable: The Craft of Code
Unbreakable: The Craft of Code
 
The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194
 
The Ring programming language version 1.10 book - Part 103 of 212
The Ring programming language version 1.10 book - Part 103 of 212The Ring programming language version 1.10 book - Part 103 of 212
The Ring programming language version 1.10 book - Part 103 of 212
 
Sql
SqlSql
Sql
 
Elixir -Tolerância a Falhas para Adultos - GDG Campinas
Elixir  -Tolerância a Falhas para Adultos - GDG CampinasElixir  -Tolerância a Falhas para Adultos - GDG Campinas
Elixir -Tolerância a Falhas para Adultos - GDG Campinas
 
Leveraging Symfony2 Forms
Leveraging Symfony2 FormsLeveraging Symfony2 Forms
Leveraging Symfony2 Forms
 
ZIO actors by Mateusz Sokół Scalac
ZIO actors by Mateusz Sokół ScalacZIO actors by Mateusz Sokół Scalac
ZIO actors by Mateusz Sokół Scalac
 
Nik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReactNik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReact
 
The Ring programming language version 1.5.4 book - Part 77 of 185
The Ring programming language version 1.5.4 book - Part 77 of 185The Ring programming language version 1.5.4 book - Part 77 of 185
The Ring programming language version 1.5.4 book - Part 77 of 185
 
Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIO
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to ask
 
Parse Everything With Elixir
Parse Everything With ElixirParse Everything With Elixir
Parse Everything With Elixir
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in Ruby
 
The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202
 
Postgres rules
Postgres rulesPostgres rules
Postgres rules
 

Similar a To be Continued - multithreading with Project Loom and Kotlin's Coroutines

ES6 patterns in the wild
ES6 patterns in the wildES6 patterns in the wild
ES6 patterns in the wildJoe Morgan
 
Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012Jo Cranford
 
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...Mateusz Zalewski
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to SwiftGiordano Scalzo
 
Empathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible codeEmpathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible codeMario Gleichmann
 
JDD 2016 - Pawel Byszewski - Kotlin, why?
JDD 2016 - Pawel Byszewski - Kotlin, why?JDD 2016 - Pawel Byszewski - Kotlin, why?
JDD 2016 - Pawel Byszewski - Kotlin, why?PROIDEA
 
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Naresha K
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionDmitry Sheiko
 
Why Scala is the better Java
Why Scala is the better JavaWhy Scala is the better Java
Why Scala is the better JavaThomas Kaiser
 
Tips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationTips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationJoni
 
Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012Anton Arhipov
 
Scala Days 2011 - Rogue: A Type-Safe DSL for MongoDB
Scala Days 2011 - Rogue: A Type-Safe DSL for MongoDBScala Days 2011 - Rogue: A Type-Safe DSL for MongoDB
Scala Days 2011 - Rogue: A Type-Safe DSL for MongoDBjorgeortiz85
 
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze..."Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...Mateusz Zalewski
 

Similar a To be Continued - multithreading with Project Loom and Kotlin's Coroutines (20)

Benefits of Kotlin
Benefits of KotlinBenefits of Kotlin
Benefits of Kotlin
 
ES6 patterns in the wild
ES6 patterns in the wildES6 patterns in the wild
ES6 patterns in the wild
 
Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012
 
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
 
Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to Swift
 
Empathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible codeEmpathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible code
 
Kotlin, why?
Kotlin, why?Kotlin, why?
Kotlin, why?
 
JDD 2016 - Pawel Byszewski - Kotlin, why?
JDD 2016 - Pawel Byszewski - Kotlin, why?JDD 2016 - Pawel Byszewski - Kotlin, why?
JDD 2016 - Pawel Byszewski - Kotlin, why?
 
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
Miracle of std lib
Miracle of std libMiracle of std lib
Miracle of std lib
 
Why Scala is the better Java
Why Scala is the better JavaWhy Scala is the better Java
Why Scala is the better Java
 
Tips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationTips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET Application
 
Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
 
mobl
moblmobl
mobl
 
Nancy + rest mow2012
Nancy + rest   mow2012Nancy + rest   mow2012
Nancy + rest mow2012
 
Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012
 
Scala Days 2011 - Rogue: A Type-Safe DSL for MongoDB
Scala Days 2011 - Rogue: A Type-Safe DSL for MongoDBScala Days 2011 - Rogue: A Type-Safe DSL for MongoDB
Scala Days 2011 - Rogue: A Type-Safe DSL for MongoDB
 
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze..."Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
 

Más de Artur Skowroński

Kopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVM
Kopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVMKopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVM
Kopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVMArtur Skowroński
 
The State of the Green IT at the beginning of 2024
The State of the Green IT at the beginning of 2024The State of the Green IT at the beginning of 2024
The State of the Green IT at the beginning of 2024Artur Skowroński
 
My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023
My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023
My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023Artur Skowroński
 
GraalVM, CRaC, Leyden and friends
GraalVM, CRaC, Leyden and friendsGraalVM, CRaC, Leyden and friends
GraalVM, CRaC, Leyden and friendsArtur Skowroński
 
Od Czarnoksiężnik z krainy Oz do modeli na produkcji
Od Czarnoksiężnik z krainy Oz do modeli na produkcjiOd Czarnoksiężnik z krainy Oz do modeli na produkcji
Od Czarnoksiężnik z krainy Oz do modeli na produkcjiArtur Skowroński
 
JVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeperJVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeperArtur Skowroński
 
JVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeperJVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeperArtur Skowroński
 
Panie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o LegacyPanie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o LegacyArtur Skowroński
 
Panie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o LegacyPanie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o LegacyArtur Skowroński
 
Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...
Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...
Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...Artur Skowroński
 
Ten Typ tak ma - O systemach typów na przykładzie TypeScript’a
Ten Typ tak ma - O systemach typów na przykładzie TypeScript’aTen Typ tak ma - O systemach typów na przykładzie TypeScript’a
Ten Typ tak ma - O systemach typów na przykładzie TypeScript’aArtur Skowroński
 
Type Systems on the example of TypeScript
Type Systems on the example of TypeScriptType Systems on the example of TypeScript
Type Systems on the example of TypeScriptArtur Skowroński
 
Google Assistant po polsku - developerski punkt widzenia
Google Assistant po polsku - developerski punkt widzeniaGoogle Assistant po polsku - developerski punkt widzenia
Google Assistant po polsku - developerski punkt widzeniaArtur Skowroński
 
Google Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różnice
Google Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różniceGoogle Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różnice
Google Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różniceArtur Skowroński
 
Blockchain: Developer's Perspective (Java Edition)
Blockchain: Developer's Perspective (Java Edition)Blockchain: Developer's Perspective (Java Edition)
Blockchain: Developer's Perspective (Java Edition)Artur Skowroński
 
Blockchain: Developer Perspective
Blockchain: Developer PerspectiveBlockchain: Developer Perspective
Blockchain: Developer PerspectiveArtur Skowroński
 
Alexa, nice to meet(js) you!
Alexa, nice to meet(js) you!Alexa, nice to meet(js) you!
Alexa, nice to meet(js) you!Artur Skowroński
 
Change Detection Anno Domini 2016
Change Detection Anno Domini 2016Change Detection Anno Domini 2016
Change Detection Anno Domini 2016Artur Skowroński
 
Embracing change - how to introduce Clojure into your company technology stac...
Embracing change - how to introduce Clojure into your company technology stac...Embracing change - how to introduce Clojure into your company technology stac...
Embracing change - how to introduce Clojure into your company technology stac...Artur Skowroński
 

Más de Artur Skowroński (20)

Kopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVM
Kopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVMKopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVM
Kopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVM
 
The State of the Green IT at the beginning of 2024
The State of the Green IT at the beginning of 2024The State of the Green IT at the beginning of 2024
The State of the Green IT at the beginning of 2024
 
My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023
My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023
My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023
 
GraalVM, CRaC, Leyden and friends
GraalVM, CRaC, Leyden and friendsGraalVM, CRaC, Leyden and friends
GraalVM, CRaC, Leyden and friends
 
Od Czarnoksiężnik z krainy Oz do modeli na produkcji
Od Czarnoksiężnik z krainy Oz do modeli na produkcjiOd Czarnoksiężnik z krainy Oz do modeli na produkcji
Od Czarnoksiężnik z krainy Oz do modeli na produkcji
 
JVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeperJVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeper
 
JVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeperJVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeper
 
Panie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o LegacyPanie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
 
Panie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o LegacyPanie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
 
Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...
Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...
Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...
 
Ten Typ tak ma - O systemach typów na przykładzie TypeScript’a
Ten Typ tak ma - O systemach typów na przykładzie TypeScript’aTen Typ tak ma - O systemach typów na przykładzie TypeScript’a
Ten Typ tak ma - O systemach typów na przykładzie TypeScript’a
 
Type Systems on the example of TypeScript
Type Systems on the example of TypeScriptType Systems on the example of TypeScript
Type Systems on the example of TypeScript
 
Google Assistant po polsku - developerski punkt widzenia
Google Assistant po polsku - developerski punkt widzeniaGoogle Assistant po polsku - developerski punkt widzenia
Google Assistant po polsku - developerski punkt widzenia
 
Google Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różnice
Google Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różniceGoogle Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różnice
Google Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różnice
 
Blockchain: Developer's Perspective (Java Edition)
Blockchain: Developer's Perspective (Java Edition)Blockchain: Developer's Perspective (Java Edition)
Blockchain: Developer's Perspective (Java Edition)
 
Blockchain: Developer Perspective
Blockchain: Developer PerspectiveBlockchain: Developer Perspective
Blockchain: Developer Perspective
 
Alexa, nice to meet you!
Alexa, nice to meet you! Alexa, nice to meet you!
Alexa, nice to meet you!
 
Alexa, nice to meet(js) you!
Alexa, nice to meet(js) you!Alexa, nice to meet(js) you!
Alexa, nice to meet(js) you!
 
Change Detection Anno Domini 2016
Change Detection Anno Domini 2016Change Detection Anno Domini 2016
Change Detection Anno Domini 2016
 
Embracing change - how to introduce Clojure into your company technology stac...
Embracing change - how to introduce Clojure into your company technology stac...Embracing change - how to introduce Clojure into your company technology stac...
Embracing change - how to introduce Clojure into your company technology stac...
 

Último

Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Christo Ananth
 
chapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineeringchapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineeringmulugeta48
 
Thermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.pptThermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.pptDineshKumar4165
 
Glass Ceramics: Processing and Properties
Glass Ceramics: Processing and PropertiesGlass Ceramics: Processing and Properties
Glass Ceramics: Processing and PropertiesPrabhanshu Chaturvedi
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...Call Girls in Nagpur High Profile
 
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptxBSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptxfenichawla
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...ranjana rawat
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...roncy bisnoi
 
Online banking management system project.pdf
Online banking management system project.pdfOnline banking management system project.pdf
Online banking management system project.pdfKamal Acharya
 
UNIT-IFLUID PROPERTIES & FLOW CHARACTERISTICS
UNIT-IFLUID PROPERTIES & FLOW CHARACTERISTICSUNIT-IFLUID PROPERTIES & FLOW CHARACTERISTICS
UNIT-IFLUID PROPERTIES & FLOW CHARACTERISTICSrknatarajan
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfJiananWang21
 
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...Call Girls in Nagpur High Profile
 
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Call Girls in Nagpur High Profile
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...ranjana rawat
 
UNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular ConduitsUNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular Conduitsrknatarajan
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingrknatarajan
 
result management system report for college project
result management system report for college projectresult management system report for college project
result management system report for college projectTonystark477637
 

Último (20)

Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
 
chapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineeringchapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineering
 
Thermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.pptThermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.ppt
 
Glass Ceramics: Processing and Properties
Glass Ceramics: Processing and PropertiesGlass Ceramics: Processing and Properties
Glass Ceramics: Processing and Properties
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
 
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptxBSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
 
(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7
(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7
(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7
 
Online banking management system project.pdf
Online banking management system project.pdfOnline banking management system project.pdf
Online banking management system project.pdf
 
UNIT-IFLUID PROPERTIES & FLOW CHARACTERISTICS
UNIT-IFLUID PROPERTIES & FLOW CHARACTERISTICSUNIT-IFLUID PROPERTIES & FLOW CHARACTERISTICS
UNIT-IFLUID PROPERTIES & FLOW CHARACTERISTICS
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
 
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
 
NFPA 5000 2024 standard .
NFPA 5000 2024 standard                                  .NFPA 5000 2024 standard                                  .
NFPA 5000 2024 standard .
 
Roadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and RoutesRoadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and Routes
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
 
UNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular ConduitsUNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular Conduits
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
 
result management system report for college project
result management system report for college projectresult management system report for college project
result management system report for college project
 

To be Continued - multithreading with Project Loom and Kotlin's Coroutines

  • 1. TO BE CONTINUED Multithreading with Project Loom and Kotlin's Coroutines ARTUR SKOWROŃSKI VIRTUSLAB
  • 3.
  • 4. SYNCHRONOUS fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 5. SYNCHRONOUS fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 6. SYNCHRONOUS fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 7. SYNCHRONOUS fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 8. SYNCHRONOUS fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 9. CALLBACKS fun main(args: Array<String>) { getLocationsNearCoordinates("SW8 5YY, UK") .success {location -> val category = location.classification.category if (category == "Store") { getStoreDetails(location.id) .success { locationWrapper -> val openingHours = locationWrapper .openingHours .first() .standardOpeningHours println("Store Opening Hours: $openingHours") } } if (category == "Office") { payOfficeRent(location.id) .success { println("Invoice paid") } } } }
  • 10. CALLBACKS fun main(args: Array<String>) { getLocationsNearCoordinates("SW8 5YY, UK") .success {location -> val category = location.classification.category if (category == "Store") { getStoreDetails(location.id) .success { locationWrapper -> val openingHours = locationWrapper .openingHours .first() .standardOpeningHours println("Store Opening Hours: $openingHours") } } if (category == "Office") { payOfficeRent(location.id) .success { println("Invoice paid") } } } }
  • 11. CALLBACKS fun main(args: Array<String>) { getLocationsNearCoordinates("SW8 5YY, UK") .success {location -> val category = location.classification.category if (category == "Store") { getStoreDetails(location.id) .success { locationWrapper -> val openingHours = locationWrapper .openingHours .first() .standardOpeningHours println("Store Opening Hours: $openingHours") } } if (category == "Office") { payOfficeRent(location.id) .success { println("Invoice paid") } } } }
  • 12. CALLBACKS fun main(args: Array<String>) { getLocationsNearCoordinates("SW8 5YY, UK") .success {location -> val category = location.classification.category if (category == "Store") { getStoreDetails(location.id) .success { locationWrapper -> val openingHours = locationWrapper .openingHours .first() .standardOpeningHours println("Store Opening Hours: $openingHours") } } if (category == "Office") { payOfficeRent(location.id) .success { println("Invoice paid") } } } }
  • 13. CALLBACKS fun main(args: Array<String>) { getLocationsNearCoordinates("SW8 5YY, UK") .success {location -> val category = location.classification.category if (category == "Store") { getStoreDetails(location.id) .success { locationWrapper -> val openingHours = locationWrapper .openingHours .first() .standardOpeningHours println("Store Opening Hours: $openingHours") } } if (category == "Office") { payOfficeRent(location.id) .success { println("Invoice paid") } } } }
  • 14. CALLBACKS fun main(args: Array<String>) { getLocationsNearCoordinates("SW8 5YY, UK") .success {location -> val category = location.classification.category if (category == "Store") { getStoreDetails(location.id) .success { locationWrapper -> val openingHours = locationWrapper .openingHours .first() .standardOpeningHours println("Store Opening Hours: $openingHours") } } if (category == "Office") { payOfficeRent(location.id) .success { println("Invoice paid") } } } }
  • 16. BRANCHING IS HARD fun combineAsync(name1: String, name2: String): CompletableFuture<Image>{ val future1 = CompletableFuture.supplyAsync(name1-> ...) val future2 = CompletableFuture.supplyAsync(name2-> ...) return future1.thenCombine(future2){i1,i2 -> ...} }
  • 19. IMPERATIVE fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 21. 1958
  • 22. 1963
  • 25. IMPERATIVE fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 26. COROUTINE fun main() { GlobalScope.launch { val location = getLocationsNearKnownPostcode().first() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } runBlocking { delay(2000L) } } suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK") } suspend fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours.first().standardOpeningHours } suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 27. COROUTINE fun main() { GlobalScope.launch { val location = getLocationsNearKnownPostcode().first() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } runBlocking { delay(2000L) } } suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK") } suspend fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours.first().standardOpeningHours } suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 28. COROUTINE fun main() { GlobalScope.launch { val location = getLocationsNearKnownPostcode().first() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } runBlocking { delay(2000L) } } suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK") } suspend fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours.first().standardOpeningHours } suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 29. COROUTINE fun main() { GlobalScope.launch { val location = getLocationsNearKnownPostcode().first() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } runBlocking { delay(2000L) } } suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK") } suspend fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours.first().standardOpeningHours } suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 30. COROUTINE fun main() { GlobalScope.launch { val location = getLocationsNearKnownPostcode().first() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } runBlocking { delay(2000L) } } suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK") } suspend fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours.first().standardOpeningHours } suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 35. DIRECT STYLE CODE Action + Result and Continuation val location = getLocationsNearKnownPostcode() val category = location.classification.category ActionResult Continuation
  • 36. CONTINUATION PASSING STYLE getLocationsNearKnownPostcode() .success {location -> val category = location.classification.category } Action Result
  • 37. CONTINUATION PASSING STYLE getLocationsNearKnownPostcode() .success {location -> val category = location.classification.category } Action Result Fancy Name for Callback Continuation
  • 38. FROM KOTLIN FILE suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK") } suspend fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours.first().standardOpeningHours } suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 39. public final static getLocationsNearKnownPostcode(Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @Lorg/jetbrains/annotations/Nullable;() // invisible @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 L0 LINENUMBER 33 L0 LDC "SW8 5YY, UK" INVOKESTATIC TescoLocationAPIKt.getLocationsNearCoordinates (Ljava/lang/String;)Ljava/util/List; ARETURN L1 MAXSTACK = 1 MAXLOCALS = 1 // access flags 0x19 // signature (Ljava/lang/String;Lkotlin/coroutines/Continuation<Ljava/lang/Object;>;)Ljava/lang/Object; // declaration: getOpeningHours(java.lang.String, kotlin.coroutines.Continuation<java.lang.Object>) public final static getOpeningHours(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @Lorg/jetbrains/annotations/Nullable;() // invisible @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 L0 LINENUMBER 37 L0 ALOAD 0 INVOKESTATIC TescoLocationAPIKt.getStoreDetails (Ljava/lang/String;)LLocationWrapper; INVOKEVIRTUAL LocationWrapper.getOpeningHours ()[LLocationOpeningHours; INVOKESTATIC kotlin/collections/ArraysKt.first ([Ljava/lang/Object;)Ljava/lang/Object; CHECKCAST LocationOpeningHours INVOKEVIRTUAL LocationOpeningHours.getStandardOpeningHours ()Ljava/util/HashMap; ARETURN L1 LOCALVARIABLE id Ljava/lang/String; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 2 // access flags 0x19 // signature (Ljava/lang/String;Lkotlin/coroutines/Continuation<Ljava/lang/Object;>;)Ljava/lang/Object; // declaration: payInvoice(java.lang.String, kotlin.coroutines.Continuation<java.lang.Object>) public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @Lorg/jetbrains/annotations/Nullable;() // invisible @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 L0 LINENUMBER 41 L0 ALOAD 0 INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult; ARETURN L1 LOCALVARIABLE id Ljava/lang/String; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 2 JVM BYTECODE
  • 40. TAKE A LOOK public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @Lorg/jetbrains/annotations/Nullable;() // invisible @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 L0 LINENUMBER 41 L0 ALOAD 0 INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult; ARETURN L1 LOCALVARIABLE id Ljava/lang/String; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 2
  • 41. TAKE A LOOK public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @Lorg/jetbrains/annotations/Nullable;() // invisible @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 L0 LINENUMBER 41 L0 ALOAD 0 INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult; ARETURN L1 LOCALVARIABLE id Ljava/lang/String; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 2 suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 42. TAKE A LOOK public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @Lorg/jetbrains/annotations/Nullable;() // invisible @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 L0 LINENUMBER 41 L0 ALOAD 0 INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult; ARETURN L1 LOCALVARIABLE id Ljava/lang/String; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 2 suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 43. public interface Continuation<in T> { public val context: CoroutineContext public fun resumeWith(result: Result<T>) }
  • 44. TAKE A LOOK public final static main()V L0 LINENUMBER 13 L0 GETSTATIC kotlinx/coroutines/GlobalScope.INSTANCE : Lkotlinx/coroutines/GlobalScope; CHECKCAST kotlinx/coroutines/CoroutineScope ACONST_NULL ACONST_NULL NEW kotlinx/coroutines/guide/compose01/CoroutineCodeKt$main$1 DUP ACONST_NULL INVOKESPECIAL kotlinx/coroutines/guide/compose01/CoroutineCodeKt$main$1.<init> (Lkotlin/coroutines/ Continuation;)V CHECKCAST kotlin/jvm/functions/Function2 ICONST_3 ACONST_NULL INVOKESTATIC kotlinx/coroutines/BuildersKt.launch$default (Lkotlinx/coroutines/ CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/ functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job; POP L1
  • 45. COROUTINE Coroutine Stack Operation 1 Operation 2 Operation 3 SUSPEND FUNCTION Operation 1 Operation 2 Operation 3 Operation 4 Operation 5 SUSPEND FUNCTION Operation 4 Operation 5 State Operation 1 Operation 2 Operation 3
  • 48. THREADS CPU SHEDULER THREAD Instruction 1 Instruction 2 Instruction 3 Instruction 4 THREAD Continuation
  • 49. OS CPU SHEDULER THREAD Instruction 1 Instruction 2 Instruction 3 Instruction 4 THREAD
  • 50. USER/KERNEL SPACE BORDER CPU SHEDULER JVM CONTEXT SWITCH
  • 53. THREAD USER/KERNEL SPACE BORDER CPU SCHEDULER JVM FORKJOINSCHEDULER THREAD THREAD THREAD
  • 54. THREAD USER/KERNEL SPACE BORDER CPU SCHEDULER JVM FORKJOINSCHEDULER THREAD Instruction 1 Instruction 2 Instruction 3 Instruction 4 Coroutines
  • 55. public class Continuation implements Runnable { public Continuation(ContinuationScope s, Runnable r) public final void run() public static void yield(ContinuationScope s) public boolean isDone() }
  • 57. var scope = new ContinuationScope("scheduler"); private final Fiber<Void> execution; execution.apply(() -> { var location = getLocationsNearKnownPostcode.yield(scope); var category = location.classification.category if (category == "Store") { var openingHours = getOpeningHours(location.id).yield(scope) System.out.println("Store Opening Hours:"+ openingHours) } if (category == "Office") payInvoice(location.id).yield() println("Invoice paid") } });
  • 58. NO MORE THREAD POOLS Thread: ~1MB Fiber: ~1KB
  • 61. RESTRICTIONS Lack of support for JNI Cannot suspend under lock Partial (emulated) support for ThreadLocal
  • 62. hg clone http://hg.openjdk.java.net/loom/loom cd loom hg update -r fibers sh configure make images JAVA 11
  • 64. SOURCES http://cr.openjdk.java.net/~rpressler/loom/Loom- Proposal.html https://www.youtube.com/watch?v=YrrUCSi72E8 KOTLINCONF 2017 - DEEP DIVE INTO COROUTINES ON JVM BY ROMAN ELIZAROV https://www.youtube.com/watch?v=vbGbXUjlRyQ PROJECT LOOM: FIBERS AND CONTINUATIONS FOR JAVA BY ALAN BATEMAN PROJECT LOOM: FIBERS AND CONTINUATIONS FOR THE JAVA VIRTUAL MACHINE