SlideShare a Scribd company logo
1 of 115
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?
Roman Elizarov
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 C 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
ORIGINAL IDEA
SCHEDULER + CONTINUATION
Thread Fiber
Strand
NEW APPROACH
COPY AS MANY API AS POSSIBLE
Thread Fiber
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
C U R R E N T T H R E A D P R O B L E M
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
P R O C E S S O R / S C O P E L O C A L S
INITIAL INTERFACE
Fiber.schedule(Executor executor, Callable callable)
OBSOLETE
Fiber.schedule(Executor executor, Callable callable)
NEW INTERFACE
try (var scope = FiberScope.open()) {
var fiber1 = scope.schedule(task);
var fiber2 = scope.schedule(task);
}
S T R U C T U R E D C O N C U R R E N C Y
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)
}
STRUCTURED CONCURRENCY
try (var scope = FiberScope.open(Option.PROPAGTE_CANCEL)) {
var fiber1 = scope.schedule(task);
var fiber2 = scope.schedule(task);
}
STRUCTURED CONCURRENCY
var deadline = Instant.now().plusSeconds(10);
try (var scope = FiberScope.open(deadline)) {
var fiber1 = scope.schedule(task);
var fiber2 = scope.schedule(task);
}
STRUCTURED CONCURRENCY
var deadline = Instant.now().plusSeconds(10);
try (var scope = FiberScope.open(deadline)) {
try (var scope2 = FiberScope.open()) {
scope2.schedule(() -> task());
}
}
STRUCTURED CONCURRENCY
var deadline = Instant.now().plusSeconds(10);
try (var scope = FiberScope.open(deadline)) {
try (var scope2 = FiberScope.open()) {
scope2.schedule(() -> task());
}
}
OBSOLETE (28.10.2019)
var deadline = Instant.now().plusSeconds(10);
try (var scope = FiberScope.open(deadline)) {
try (var scope2 = FiberScope.open()) {
scope2.schedule(() -> task());
}
}
D O N E W H E N I T ’ S D O N E
INSTALLATION STEPS
ONLY FOR JAVA => 11
hg clone https://github.com/openjdk/loom
cd loom
hg update -r fibers
sh configure
make images
OBSOLETE (23.08.2019)
hg clone https://github.com/openjdk/loom
cd loom
hg update -r fibers
sh configure
make images
P R O J E C T L O O M O N G I T
EARLY ACCESS BUILDS
2019/7/25
hg clone https://github.com/openjdk/loom
cd loom
hg update -r fibers
sh configure
make images
EARLY ACCESS BUILDS
2019/7/25
D AY 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

Tablas, Codigos Base De Datos Excelsa
Tablas, Codigos Base De Datos ExcelsaTablas, Codigos Base De Datos Excelsa
Tablas, Codigos Base De Datos Excelsa
Héctor
 
Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3
guesta3202
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemy
Inada Naoki
 
Revision c odesagain
Revision c odesagainRevision c odesagain
Revision c odesagain
rex0721
 
Introduccion administracion
Introduccion administracionIntroduccion administracion
Introduccion administracion
MARSHY LABK
 

What's hot (17)

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
 
Tablas, Codigos Base De Datos Excelsa
Tablas, Codigos Base De Datos ExcelsaTablas, Codigos Base De Datos Excelsa
Tablas, Codigos Base De Datos Excelsa
 
Postgres rules
Postgres rulesPostgres rules
Postgres rules
 
Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3
 
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
 
PHP cart
PHP cartPHP cart
PHP cart
 
redis überall
redis überallredis überall
redis überall
 
Syntactic sugar in postgre sql
Syntactic sugar in postgre sqlSyntactic sugar in postgre sql
Syntactic sugar in postgre sql
 
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...
 
Beautiful python - PyLadies
Beautiful python - PyLadiesBeautiful python - PyLadies
Beautiful python - PyLadies
 
Syntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQLSyntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQL
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan Soares
 
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)
 
Revision c odesagain
Revision c odesagainRevision c odesagain
Revision c odesagain
 
Programa simulacion de ventas de aeropuerto
Programa simulacion de ventas de aeropuertoPrograma simulacion de ventas de aeropuerto
Programa simulacion de ventas de aeropuerto
 
Introduccion administracion
Introduccion administracionIntroduccion administracion
Introduccion administracion
 

Similar to Ciąg dalszy nastąpi - o wielowątkowości, Projekcie Loom i kotlinowych Korutynach

Simple design/programming nuggets
Simple design/programming nuggetsSimple design/programming nuggets
Simple design/programming nuggets
Vivek Singh
 

Similar to Ciąg dalszy nastąpi - o wielowątkowości, Projekcie Loom i kotlinowych Korutynach (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
 
Benefits of Kotlin
Benefits of KotlinBenefits of Kotlin
Benefits of Kotlin
 
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
 
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
 
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
 
Miracle of std lib
Miracle of std libMiracle of std lib
Miracle of std lib
 
Simple design/programming nuggets
Simple design/programming nuggetsSimple design/programming nuggets
Simple design/programming nuggets
 
Neo4 J
Neo4 J Neo4 J
Neo4 J
 
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 - 혼자 공부하면 분명히 안할테니까 같이 공부하기
 
Classic Games Development with Drools
Classic Games Development with DroolsClassic Games Development with Drools
Classic Games Development with Drools
 
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
 
Elegant objects
Elegant objectsElegant objects
Elegant objects
 
06 Map Reduce
06 Map Reduce06 Map Reduce
06 Map Reduce
 
Tactical DDD patterns in Go
Tactical DDD patterns in GoTactical DDD patterns in Go
Tactical DDD patterns in Go
 

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

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

Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
dollysharma2066
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ssuser89054b
 
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort ServiceCall Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
dharasingh5698
 
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
dharasingh5698
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Christo Ananth
 

Recently uploaded (20)

KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghly
 
Water Industry Process Automation & Control Monthly - April 2024
Water Industry Process Automation & Control Monthly - April 2024Water Industry Process Automation & Control Monthly - April 2024
Water Industry Process Automation & Control Monthly - April 2024
 
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performance
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)
 
Unit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdfUnit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdf
 
Thermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.pptThermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.ppt
 
Online banking management system project.pdf
Online banking management system project.pdfOnline banking management system project.pdf
Online banking management system project.pdf
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
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...
 
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort ServiceCall Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
 
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
 
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
 
(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7
(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7
(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7
 
Bhosari ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready For ...
Bhosari ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready For ...Bhosari ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready For ...
Bhosari ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready For ...
 
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
 
University management System project report..pdf
University management System project report..pdfUniversity management System project report..pdf
University management System project report..pdf
 
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
 

Ciąg dalszy nastąpi - o wielowątkowości, Projekcie Loom i kotlinowych Korutynach

  • 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
  • 38. 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) }
  • 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) }
  • 43. 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) }
  • 47. C O N T I N U AT I O N S
  • 48. C O N T I N U AT I O N S
  • 49. DIRECT STYLE CODE val location = getLocationsNearKnownPostcode() val category = location.classification.category ActionResult Continuation ACTION + RESULT & CONTINUATION
  • 50. CONTINUATION PASSING STYLE getLocationsNearKnownPostcode() .success {location -> val category = location.classification.category } Action Result
  • 51. CONTINUATION PASSING STYLE getLocationsNearKnownPostcode() .success {location -> val category = location.classification.category } Action Result FANCY NAME FOR CALLBACKS
  • 52. 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) }
  • 53. 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
  • 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
  • 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. 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) }
  • 57. CONTINUATION INTERFACE public interface Continuation<in T> { public val context: CoroutineContext public fun resumeWith(result: Result<T>) }
  • 58. 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
  • 59. 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
  • 60. P R O J E C T L O O M
  • 61. O P E R AT I N G S Y S T E M S 1 0 1
  • 62. 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
  • 63. KERNEL SPACE THREADS C P U S C H E D U L E R THREAD Instruction 1 Instruction 2 Instruction 3 Instruction 4 THREAD Continuation
  • 64. OS C P U S H E D U L E R THREAD THREAD Instruction 1 Instruction 2 Instruction 3 Instruction 4
  • 65. USER/KERNEL SPACE BORDER CPU SHEDULER JVM CONTEXT SWITCH
  • 66. P R O J E C T M E T R O P O L I S
  • 67. P R O J E C T VA L H A L L A
  • 68. P R O J E C T PA N A M A
  • 69. P R O J E C T A M B E R
  • 70. P R O J E C T L O O M
  • 71. USER/KERNEL SPACE BORDER CPU SCHEDULER JVM FORKJOINSCHEDULER THREAD THREAD THREAD
  • 72. USER/KERNEL SPACE BORDER CPU SCHEDULER JVM FORKJOINSCHEDULER THREAD Instruction 1 Instruction 2 Instruction 3 Instruction 4 Coroutines
  • 73. 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() }
  • 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. 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) }
  • 80. G E N E R AT O R S
  • 81. ORIGINAL IDEA SCHEDULER + CONTINUATION Thread Fiber Strand
  • 82. NEW APPROACH COPY AS MANY API AS POSSIBLE Thread Fiber
  • 83. G A I N S
  • 84. T H R E A D S - ~ 1 M B
  • 85. F I B E R - ~ 1 K B
  • 86. N O M O R E T H R E A D P O O L S
  • 87. L A C K O F C O M M O N A B S T R A C T I O N
  • 88. D R A W B A C K S
  • 89. C U R R E N T T H R E A D P R O B L E M
  • 90. L A C K O F J N I S U P P O R T
  • 91. C A N N O T S U S P E N D U N D E R L O C K
  • 92. T H R E A D L O C A L
  • 93. P R O C E S S O R / S C O P E L O C A L S
  • 94.
  • 97. NEW INTERFACE try (var scope = FiberScope.open()) { var fiber1 = scope.schedule(task); var fiber2 = scope.schedule(task); }
  • 98. S T R U C T U R E D C O N C U R R E N C Y
  • 99. 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) }
  • 100. STRUCTURED CONCURRENCY try (var scope = FiberScope.open(Option.PROPAGTE_CANCEL)) { var fiber1 = scope.schedule(task); var fiber2 = scope.schedule(task); }
  • 101. STRUCTURED CONCURRENCY var deadline = Instant.now().plusSeconds(10); try (var scope = FiberScope.open(deadline)) { var fiber1 = scope.schedule(task); var fiber2 = scope.schedule(task); }
  • 102. STRUCTURED CONCURRENCY var deadline = Instant.now().plusSeconds(10); try (var scope = FiberScope.open(deadline)) { try (var scope2 = FiberScope.open()) { scope2.schedule(() -> task()); } }
  • 103. STRUCTURED CONCURRENCY var deadline = Instant.now().plusSeconds(10); try (var scope = FiberScope.open(deadline)) { try (var scope2 = FiberScope.open()) { scope2.schedule(() -> task()); } }
  • 104. OBSOLETE (28.10.2019) var deadline = Instant.now().plusSeconds(10); try (var scope = FiberScope.open(deadline)) { try (var scope2 = FiberScope.open()) { scope2.schedule(() -> task()); } }
  • 105. D O N E W H E N I T ’ S D O N E
  • 106. INSTALLATION STEPS ONLY FOR JAVA => 11 hg clone https://github.com/openjdk/loom cd loom hg update -r fibers sh configure make images
  • 107. OBSOLETE (23.08.2019) hg clone https://github.com/openjdk/loom cd loom hg update -r fibers sh configure make images
  • 108. P R O J E C T L O O M O N G I T
  • 109. EARLY ACCESS BUILDS 2019/7/25 hg clone https://github.com/openjdk/loom cd loom hg update -r fibers sh configure make images
  • 111. D AY B E F O R E M E E T U P
  • 112.
  • 113.
  • 114. 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
  • 115. GQ U E S T I O N S ?