SlideShare a Scribd company logo
1 of 95
Download to read offline
TO B E CO N T I N U E D
K O T L I N C O U R O U T I N E S & P R O J E C T L O O M
A R T U R S KO W R O Ń S K I  
A N Y B O D Y K O T L I N ?
B Y J E T B R A I N S
2 0 1 1
K O T L I N 1 . 3
1 0 . 2 0 1 8
K O T L I N 1 . 3
1 0 . 2 0 1 8
COROUTINES
W I L L T E A C H Y O U H O W C O R O U T I N E S W O R K S
W O N ’ T T E A C H Y O U H O W - T O - C O R O U T I N E
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")
}
}
}
}
A LT E R N AT I V E S
COMPUTABLE FUTURES
fun combineAsync(name1: String, name2: String): CompletableFuture<Image>{
val future1 = CompletableFuture.supplyAsync(name1-> ...)
val future2 = CompletableFuture.supplyAsync(name2-> ...)
return future1.thenCombine(future2){i1,i2 -> ...}
}
REACTIVE EXTENSIONS
Observable<String> getTitle() {
return Observable.from(titleList);
}
Observable.just("book1", "book2")
.flatMap(s -> getTitle())
.subscribe(l -> result += l);
assertTrue(result.equals("titletitle"));
C O M P L E X I T Y
E X C E P T I O N H A N D L I N G I S H A R D
O V E R A L L I T ’ S H A R D
IMPERATIVE CODE
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)
}
C O R O U T I N E S
1 9 5 8
1 9 6 3
NATIVE SUPPORT
NATIVE?
IMPERATIVE CODE
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 CODE
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 CODE
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 CODE
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 CODE
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 CODE
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)
}
BLOCKING
THREAD
Function 1
Function 2
SUSPEND
Suspension Point
THREAD
Function 1
Function 2
SUSPEND
THREAD
Coroutine 1
Function 2
getLocationsNearKnownPostcode getOpeningHours
Function 3
C O N T I N U AT I O N S
C O N T I N U AT I O N S
DIRECT STYLE CODE
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
ActionResult
Continuation
ACTION + RESULT & 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 CALLBACKS
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)
}
JVM BYTECODE
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
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)
}
CONTINUATION INTERFACE
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
TAKE A LOOK
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
P R O J E C T L O O M
O P E R AT I N G S Y S T E M S 1 0 1
KERNEL SPACE THREADS
P R O C E S S E S
K E R N E L T H R E A D S
OS
PROCESS
PROCESS
THREAD
THREAD
THREAD
THREAD
KERNEL SPACE THREADS
C P U S H E D U L E R
THREAD
Instruction 1
Instruction 2
Instruction 3
Instruction 4
THREAD
Continuation
OS
C P U S H E D U L E R
THREAD
THREAD
Instruction 1
Instruction 2
Instruction 3
Instruction 4
USER/KERNEL SPACE BORDER
CPU SHEDULER JVM
CONTEXT SWITCH
P R O J E C T M E T R O P O L I S
P R O J E C T VA L H A L L A
P R O J E C T PA N A M A
P R O J E C T A M B E R
P R O J E C T L O O M
USER/KERNEL SPACE BORDER
CPU SCHEDULER JVM
FORKJOINSCHEDULER
THREAD
THREAD
THREAD
USER/KERNEL SPACE BORDER
CPU SCHEDULER JVM
FORKJOINSCHEDULER
THREAD
Instruction 1
Instruction 2
Instruction 3
Instruction 4
Coroutines
CONTINUATION INTERFACE
public class Continuation implements Runnable {
public Continuation(ContinuationScope s, Runnable r)
public final void run()
public static void yield(ContinuationScope s)
public boolean isDone()
}
CONTINUATIONS
public static void main(String[] args){
ContinuationScope scope = new ContinuationScope("scope")
Continuation continuation = new Continuation(scope, () ->{
var location = getLocationsNearKnownPostcode()
var category = location.classification.category
if (category.equals(”Store”)) {
var openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category.equals(“Office")) {
payInvoice(location.id)
println("Invoice paid")
}
})
while (!continuation.isDone()) {
continuation.run();
}
}
public List<LocationWrapper> getLocationNearKnownPostcode() {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
public OpeningHours getOpeningHours(id: String) {
return getStoreDetails(id).openingHours
}
public void payInvoice(id: String) {
return payOfficeRent(id)
}
CONTINUATIONS
public static void main(String[] args){
ContinuationScope scope = new ContinuationScope("scope")
Continuation continuation = new Continuation(scope, () ->{
var location = getLocationsNearKnownPostcode()
var category = location.classification.category
if (category.equals(”Store”)) {
var openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category.equals(“Office")) {
payInvoice(location.id)
println("Invoice paid")
}
})
while (!continuation.isDone()) {
continuation.run();
}
}
public List<LocationWrapper> getLocationNearKnownPostcode() {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
public OpeningHours getOpeningHours(id: String) {
return getStoreDetails(id).openingHours
}
public void payInvoice(id: String) {
return payOfficeRent(id)
}
CONTINUATIONS
public static void main(String[] args){
ContinuationScope scope = new ContinuationScope("scope")
Continuation continuation = new Continuation(scope, () ->{
var location = getLocationsNearKnownPostcode()
var category = location.classification.category
if (category.equals(”Store”)) {
var openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category.equals(“Office")) {
payInvoice(location.id)
println("Invoice paid")
}
})
while (!continuation.isDone()) {
continuation.run();
}
}
public List<LocationWrapper> getLocationNearKnownPostcode() {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
public OpeningHours getOpeningHours(id: String) {
return getStoreDetails(id).openingHours
}
public void payInvoice(id: String) {
return payOfficeRent(id)
}
CONTINUATIONS
public static void main(String[] args){
ContinuationScope scope = new ContinuationScope("scope")
Continuation continuation = new Continuation(scope, () ->{
var location = getLocationsNearKnownPostcode()
var category = location.classification.category
if (category.equals(”Store”)) {
var openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category.equals(“Office")) {
payInvoice(location.id)
println("Invoice paid")
}
})
while (!continuation.isDone()) {
continuation.run();
}
}
public List<LocationWrapper> getLocationNearKnownPostcode() {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
public OpeningHours getOpeningHours(id: String) {
return getStoreDetails(id).openingHours
}
public void payInvoice(id: String) {
return payOfficeRent(id)
}
CONTINUATIONS
public static void main(String[] args){
ContinuationScope scope = new ContinuationScope("scope")
Continuation continuation = new Continuation(scope, () ->{
var location = getLocationsNearKnownPostcode()
var category = location.classification.category
if (category.equals(”Store”)) {
var openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category.equals(“Office")) {
payInvoice(location.id)
println("Invoice paid")
}
})
while (!continuation.isDone()) {
continuation.run();
}
}
public List<LocationWrapper> getLocationNearKnownPostcode() {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
public OpeningHours getOpeningHours(id: String) {
return getStoreDetails(id).openingHours
}
public void payInvoice(id: String) {
return payOfficeRent(id)
}
CONTINUATIONS
public static void main(String[] args){
ContinuationScope scope = new ContinuationScope("scope")
Continuation continuation = new Continuation(scope, () ->{
var location = getLocationsNearKnownPostcode()
var category = location.classification.category
if (category.equals(”Store”)) {
var openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category.equals(“Office")) {
payInvoice(location.id)
println("Invoice paid")
}
})
while (!continuation.isDone()) {
continuation.run();
}
}
public List<LocationWrapper> getLocationNearKnownPostcode() {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
public OpeningHours getOpeningHours(id: String) {
return getStoreDetails(id).openingHours
}
public void payInvoice(id: String) {
return payOfficeRent(id)
}
G E N E R AT O R S
FIBER
SCHEDULER + CONTINUATION
Thread Fiber
Strand
FIBER INTERFACE
Fiber.schedule(Executor executor, Callable callable)
G A I N S
T H R E A D S - ~ 1 M B
F I B E R - ~ 1 K B
N O M O R E T H R E A D P O O L S
L A C K O F C O M M O N A B S T R A C T I O N
D R A W B A C K S
L A C K O F J N I S U P P O R T
C A N N O T S U S P E N D U N D E R L O C K
T H R E A D L O C A L
INSTALLATION STEPS
ONLY FOR JAVA => 11
hg clone http://hg.openjdk.java.net/loom/loom
cd loom
hg update -r fibers
sh configure
make images
D O N E W H E N I T ’ S D O N E
1 0 M I N U T E S B E F O R E M E E T U P
S O U R C E S
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
GQ U E S T I O N S ?

More Related Content

What's hot

The Art of Transduction
The Art of TransductionThe Art of Transduction
The Art of TransductionDavid Stockton
 
The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189Mahmoud Samir Fayed
 
PHP webboard
PHP webboardPHP webboard
PHP webboardtumetr1
 
Tablas, Codigos Base De Datos Excelsa
Tablas, Codigos Base De Datos ExcelsaTablas, Codigos Base De Datos Excelsa
Tablas, Codigos Base De Datos ExcelsaHéctor
 
PHP cart
PHP cartPHP cart
PHP carttumetr1
 
Postgres rules
Postgres rulesPostgres rules
Postgres rulesgisborne
 
Syntactic sugar in postgre sql
Syntactic sugar in postgre sqlSyntactic sugar in postgre sql
Syntactic sugar in postgre sqlAntony Abramchenko
 
The Ring programming language version 1.2 book - Part 32 of 84
The Ring programming language version 1.2 book - Part 32 of 84The Ring programming language version 1.2 book - Part 32 of 84
The Ring programming language version 1.2 book - Part 32 of 84Mahmoud Samir Fayed
 
Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3guesta3202
 
Syntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQLSyntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQLAntony Abramchenko
 
redis überall
redis überallredis überall
redis überallzucaritask
 
Beautiful python - PyLadies
Beautiful python - PyLadiesBeautiful python - PyLadies
Beautiful python - PyLadiesAlicia Pérez
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemyInada Naoki
 
Anna Karenina (leon tolstoi)
Anna Karenina (leon tolstoi)Anna Karenina (leon tolstoi)
Anna Karenina (leon tolstoi)Rita Dinis
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresiMasters
 
Introduccion administracion
Introduccion administracionIntroduccion administracion
Introduccion administracionMARSHY LABK
 
Programa simulacion de ventas de aeropuerto
Programa simulacion de ventas de aeropuertoPrograma simulacion de ventas de aeropuerto
Programa simulacion de ventas de aeropuertoAnel Sosa
 

What's hot (18)

The Art of Transduction
The Art of TransductionThe Art of Transduction
The Art of Transduction
 
The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189
 
PHP webboard
PHP webboardPHP webboard
PHP webboard
 
Tablas, Codigos Base De Datos Excelsa
Tablas, Codigos Base De Datos ExcelsaTablas, Codigos Base De Datos Excelsa
Tablas, Codigos Base De Datos Excelsa
 
PHP cart
PHP cartPHP cart
PHP cart
 
Postgres rules
Postgres rulesPostgres rules
Postgres rules
 
Syntactic sugar in postgre sql
Syntactic sugar in postgre sqlSyntactic sugar in postgre sql
Syntactic sugar in postgre sql
 
The Ring programming language version 1.2 book - Part 32 of 84
The Ring programming language version 1.2 book - Part 32 of 84The Ring programming language version 1.2 book - Part 32 of 84
The Ring programming language version 1.2 book - Part 32 of 84
 
Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3
 
Zadania z rozwiazaniami - powtórzenie funkcji kwadratowej na poziomie podstaw...
Zadania z rozwiazaniami - powtórzenie funkcji kwadratowej na poziomie podstaw...Zadania z rozwiazaniami - powtórzenie funkcji kwadratowej na poziomie podstaw...
Zadania z rozwiazaniami - powtórzenie funkcji kwadratowej na poziomie podstaw...
 
Syntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQLSyntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQL
 
redis überall
redis überallredis überall
redis überall
 
Beautiful python - PyLadies
Beautiful python - PyLadiesBeautiful python - PyLadies
Beautiful python - PyLadies
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemy
 
Anna Karenina (leon tolstoi)
Anna Karenina (leon tolstoi)Anna Karenina (leon tolstoi)
Anna Karenina (leon tolstoi)
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan Soares
 
Introduccion administracion
Introduccion administracionIntroduccion administracion
Introduccion administracion
 
Programa simulacion de ventas de aeropuerto
Programa simulacion de ventas de aeropuertoPrograma simulacion de ventas de aeropuerto
Programa simulacion de ventas de aeropuerto
 

Similar to To Be Continued - multithreading with Project Loom and Kotlin's Coroutines

[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
 
ES6 patterns in the wild
ES6 patterns in the wildES6 patterns in the wild
ES6 patterns in the wildJoe Morgan
 
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
 
"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
 
Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012Jo Cranford
 
Simple design/programming nuggets
Simple design/programming nuggetsSimple design/programming nuggets
Simple design/programming nuggetsVivek Singh
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to SwiftGiordano Scalzo
 
Hitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional ProgrammingHitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional ProgrammingSergey Shishkin
 
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Suyeol Jeon
 
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
 
Classic Games Development with Drools
Classic Games Development with DroolsClassic Games Development with Drools
Classic Games Development with DroolsMark Proctor
 
Combatendo code smells em Java
Combatendo code smells em Java Combatendo code smells em Java
Combatendo code smells em Java Emmanuel Neri
 
import java.util.ArrayList;public class Checkout{private.docx
import java.util.ArrayList;public class Checkout{private.docximport java.util.ArrayList;public class Checkout{private.docx
import java.util.ArrayList;public class Checkout{private.docxAbhinav816839
 

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

[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ć ...
 
ES6 patterns in the wild
ES6 patterns in the wildES6 patterns in the wild
ES6 patterns in the wild
 
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
 
Benefits of Kotlin
Benefits of KotlinBenefits of Kotlin
Benefits of Kotlin
 
Swift Study #2
Swift Study #2Swift Study #2
Swift Study #2
 
"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...
 
Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012
 
Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
 
Neo4 J
Neo4 J Neo4 J
Neo4 J
 
Simple design/programming nuggets
Simple design/programming nuggetsSimple design/programming nuggets
Simple design/programming nuggets
 
Miracle of std lib
Miracle of std libMiracle of std lib
Miracle of std lib
 
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
 
Hitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional ProgrammingHitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional Programming
 
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
 
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
 
Classic Games Development with Drools
Classic Games Development with DroolsClassic Games Development with Drools
Classic Games Development with Drools
 
Combatendo code smells em Java
Combatendo code smells em Java Combatendo code smells em Java
Combatendo code smells em Java
 
import java.util.ArrayList;public class Checkout{private.docx
import java.util.ArrayList;public class Checkout{private.docximport java.util.ArrayList;public class Checkout{private.docx
import java.util.ArrayList;public class Checkout{private.docx
 
Elegant objects
Elegant objectsElegant objects
Elegant objects
 

More from 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
 

More from 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...
 

Recently uploaded

Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 

Recently uploaded (20)

Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 

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

  • 1. TO B E CO N T I N U E D K O T L I N C O U R O U T I N E S & P R O J E C T L O O M A R T U R S KO W R O Ń S K I  
  • 2.
  • 3.
  • 4. A N Y B O D Y K O T L I N ?
  • 5. B Y J E T B R A I N S 2 0 1 1
  • 6.
  • 7.
  • 8. K O T L I N 1 . 3 1 0 . 2 0 1 8
  • 9. K O T L I N 1 . 3 1 0 . 2 0 1 8 COROUTINES
  • 10. W I L L T E A C H Y O U H O W C O R O U T I N E S W O R K S
  • 11. W O N ’ T T E A C H Y O U H O W - T O - C O R O U T I N E
  • 12.
  • 13. 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) }
  • 14. 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) }
  • 15. 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) }
  • 16. 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) }
  • 17. 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) }
  • 18. 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") } } } }
  • 19. 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") } } } }
  • 20. 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") } } } }
  • 21. 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") } } } }
  • 22. 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") } } } }
  • 23. 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") } } } }
  • 24. A LT E R N AT I V E S
  • 25. COMPUTABLE FUTURES fun combineAsync(name1: String, name2: String): CompletableFuture<Image>{ val future1 = CompletableFuture.supplyAsync(name1-> ...) val future2 = CompletableFuture.supplyAsync(name2-> ...) return future1.thenCombine(future2){i1,i2 -> ...} }
  • 26. REACTIVE EXTENSIONS Observable<String> getTitle() { return Observable.from(titleList); } Observable.just("book1", "book2") .flatMap(s -> getTitle()) .subscribe(l -> result += l); assertTrue(result.equals("titletitle"));
  • 27. C O M P L E X I T Y
  • 28. E X C E P T I O N H A N D L I N G I S H A R D
  • 29. O V E R A L L I T ’ S H A R D
  • 30. IMPERATIVE CODE 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) }
  • 31. C O R O U T I N E S
  • 32. 1 9 5 8
  • 33.
  • 34. 1 9 6 3
  • 37. IMPERATIVE CODE 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) }
  • 38. COROUTINE CODE 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) }
  • 39. COROUTINE CODE 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) }
  • 40. COROUTINE CODE 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) }
  • 41. COROUTINE CODE 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) }
  • 42. COROUTINE CODE 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) }
  • 46. C O N T I N U AT I O N S
  • 47. C O N T I N U AT I O N S
  • 48. DIRECT STYLE CODE val location = getLocationsNearKnownPostcode() val category = location.classification.category ActionResult Continuation ACTION + RESULT & CONTINUATION
  • 49. CONTINUATION PASSING STYLE getLocationsNearKnownPostcode() .success {location -> val category = location.classification.category } Action Result
  • 50. CONTINUATION PASSING STYLE getLocationsNearKnownPostcode() .success {location -> val category = location.classification.category } Action Result FANCY NAME FOR CALLBACKS
  • 51. 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) }
  • 52. JVM BYTECODE 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
  • 53. 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
  • 54. 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) }
  • 55. 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) }
  • 56. CONTINUATION INTERFACE public interface Continuation<in T> { public val context: CoroutineContext public fun resumeWith(result: Result<T>) }
  • 57. 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
  • 58. TAKE A LOOK 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
  • 59. P R O J E C T L O O M
  • 60. O P E R AT I N G S Y S T E M S 1 0 1
  • 61. KERNEL SPACE THREADS P R O C E S S E S K E R N E L T H R E A D S OS PROCESS PROCESS THREAD THREAD THREAD THREAD
  • 62. KERNEL SPACE THREADS C P U S H E D U L E R THREAD Instruction 1 Instruction 2 Instruction 3 Instruction 4 THREAD Continuation
  • 63. OS C P U S H E D U L E R THREAD THREAD Instruction 1 Instruction 2 Instruction 3 Instruction 4
  • 64. USER/KERNEL SPACE BORDER CPU SHEDULER JVM CONTEXT SWITCH
  • 65. P R O J E C T M E T R O P O L I S
  • 66. P R O J E C T VA L H A L L A
  • 67. P R O J E C T PA N A M A
  • 68. P R O J E C T A M B E R
  • 69. P R O J E C T L O O M
  • 70. USER/KERNEL SPACE BORDER CPU SCHEDULER JVM FORKJOINSCHEDULER THREAD THREAD THREAD
  • 71. USER/KERNEL SPACE BORDER CPU SCHEDULER JVM FORKJOINSCHEDULER THREAD Instruction 1 Instruction 2 Instruction 3 Instruction 4 Coroutines
  • 72. CONTINUATION INTERFACE public class Continuation implements Runnable { public Continuation(ContinuationScope s, Runnable r) public final void run() public static void yield(ContinuationScope s) public boolean isDone() }
  • 73. CONTINUATIONS public static void main(String[] args){ ContinuationScope scope = new ContinuationScope("scope") Continuation continuation = new Continuation(scope, () ->{ var location = getLocationsNearKnownPostcode() var category = location.classification.category if (category.equals(”Store”)) { var openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category.equals(“Office")) { payInvoice(location.id) println("Invoice paid") } }) while (!continuation.isDone()) { continuation.run(); } } public List<LocationWrapper> getLocationNearKnownPostcode() { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } public OpeningHours getOpeningHours(id: String) { return getStoreDetails(id).openingHours } public void payInvoice(id: String) { return payOfficeRent(id) }
  • 74. CONTINUATIONS public static void main(String[] args){ ContinuationScope scope = new ContinuationScope("scope") Continuation continuation = new Continuation(scope, () ->{ var location = getLocationsNearKnownPostcode() var category = location.classification.category if (category.equals(”Store”)) { var openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category.equals(“Office")) { payInvoice(location.id) println("Invoice paid") } }) while (!continuation.isDone()) { continuation.run(); } } public List<LocationWrapper> getLocationNearKnownPostcode() { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } public OpeningHours getOpeningHours(id: String) { return getStoreDetails(id).openingHours } public void payInvoice(id: String) { return payOfficeRent(id) }
  • 75. CONTINUATIONS public static void main(String[] args){ ContinuationScope scope = new ContinuationScope("scope") Continuation continuation = new Continuation(scope, () ->{ var location = getLocationsNearKnownPostcode() var category = location.classification.category if (category.equals(”Store”)) { var openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category.equals(“Office")) { payInvoice(location.id) println("Invoice paid") } }) while (!continuation.isDone()) { continuation.run(); } } public List<LocationWrapper> getLocationNearKnownPostcode() { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } public OpeningHours getOpeningHours(id: String) { return getStoreDetails(id).openingHours } public void payInvoice(id: String) { return payOfficeRent(id) }
  • 76. CONTINUATIONS public static void main(String[] args){ ContinuationScope scope = new ContinuationScope("scope") Continuation continuation = new Continuation(scope, () ->{ var location = getLocationsNearKnownPostcode() var category = location.classification.category if (category.equals(”Store”)) { var openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category.equals(“Office")) { payInvoice(location.id) println("Invoice paid") } }) while (!continuation.isDone()) { continuation.run(); } } public List<LocationWrapper> getLocationNearKnownPostcode() { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } public OpeningHours getOpeningHours(id: String) { return getStoreDetails(id).openingHours } public void payInvoice(id: String) { return payOfficeRent(id) }
  • 77. CONTINUATIONS public static void main(String[] args){ ContinuationScope scope = new ContinuationScope("scope") Continuation continuation = new Continuation(scope, () ->{ var location = getLocationsNearKnownPostcode() var category = location.classification.category if (category.equals(”Store”)) { var openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category.equals(“Office")) { payInvoice(location.id) println("Invoice paid") } }) while (!continuation.isDone()) { continuation.run(); } } public List<LocationWrapper> getLocationNearKnownPostcode() { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } public OpeningHours getOpeningHours(id: String) { return getStoreDetails(id).openingHours } public void payInvoice(id: String) { return payOfficeRent(id) }
  • 78. CONTINUATIONS public static void main(String[] args){ ContinuationScope scope = new ContinuationScope("scope") Continuation continuation = new Continuation(scope, () ->{ var location = getLocationsNearKnownPostcode() var category = location.classification.category if (category.equals(”Store”)) { var openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category.equals(“Office")) { payInvoice(location.id) println("Invoice paid") } }) while (!continuation.isDone()) { continuation.run(); } } public List<LocationWrapper> getLocationNearKnownPostcode() { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } public OpeningHours getOpeningHours(id: String) { return getStoreDetails(id).openingHours } public void payInvoice(id: String) { return payOfficeRent(id) }
  • 79. G E N E R AT O R S
  • 82. G A I N S
  • 83. T H R E A D S - ~ 1 M B
  • 84. F I B E R - ~ 1 K B
  • 85. N O M O R E T H R E A D P O O L S
  • 86. L A C K O F C O M M O N A B S T R A C T I O N
  • 87. D R A W B A C K S
  • 88. L A C K O F J N I S U P P O R T
  • 89. C A N N O T S U S P E N D U N D E R L O C K
  • 90. T H R E A D L O C A L
  • 91. INSTALLATION STEPS ONLY FOR JAVA => 11 hg clone http://hg.openjdk.java.net/loom/loom cd loom hg update -r fibers sh configure make images
  • 92. D O N E W H E N I T ’ S D O N E
  • 93. 1 0 M I N U T E S B E F O R E M E E T U P
  • 94. S O U R C E S 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
  • 95. GQ U E S T I O N S ?