puniverse / quasar

Fibers, Channels and Actors for the JVM
http://docs.paralleluniverse.co/quasar/
Other
4.56k stars 575 forks source link

Fiber.sleep Caused the loss of "tasks" #311

Open yuri-li opened 6 years ago

yuri-li commented 6 years ago
import co.paralleluniverse.fibers.Fiber

fun main(args: Array<String>) {
  Fiber<Void>{
        (1..3).forEach {
            println("current value: ${it}")
            Fiber.sleep(1000)
        }
    }.start()
}

please run it "gradle -q run",observe what the console prints Why only output 2? 3 was eaten?

yuri-li commented 6 years ago

I don't know the reason, but the problem has been solved by changing the codding.

import co.paralleluniverse.fibers.Fiber
import co.paralleluniverse.fibers.Suspendable
import co.paralleluniverse.kotlin.fiber
import java.util.concurrent.TimeUnit

fun main(args: Array<String>) {
    fiber @Suspendable {
        (1..3).forEach {
            Fiber.park({ println("current value: ${it}") }.invoke(), 1000, TimeUnit.MILLISECONDS)
            Fiber.currentFiber().unpark()
        }
    }
}

In addition, the language I use is kotlin

yuri-li commented 6 years ago
import co.paralleluniverse.fibers.Fiber
import co.paralleluniverse.fibers.Suspendable
import co.paralleluniverse.kotlin.fiber
import java.util.concurrent.TimeUnit

fun main(args: Array<String>) {
    fiber @Suspendable {
        (1..3).forEach {
            println("current value: ${it}")
            Fiber.sleep(1000)
        }
    }.get(4, TimeUnit.SECONDS)
}
yuri-li commented 6 years ago
import co.paralleluniverse.fibers.Fiber
import co.paralleluniverse.fibers.Suspendable
import co.paralleluniverse.kotlin.fiber

fun main(args: Array<String>) {
    fiber @Suspendable {
        (1..3).forEach {
            println("current value: ${it}")
            Fiber.sleep(1000)
        }
    }.join()
}
yuri-li commented 6 years ago

If the above problem is solved, think about the following code:

import co.paralleluniverse.fibers.Fiber
import co.paralleluniverse.fibers.Suspendable
import co.paralleluniverse.kotlin.fiber

fun main(args: Array<String>) {
    fiber @Suspendable {
        (1..3).forEach {
            println("fiber name f1, current value: ${it}")
            Fiber.sleep(1000)
        }
    }

    fiber @Suspendable {
        (1..3).forEach {
            println("fiber name f2, current value: ${it}")
            Fiber.sleep(1000)
        }
    }
}
yuri-li commented 6 years ago

I know.

import co.paralleluniverse.fibers.Fiber
import co.paralleluniverse.fibers.Suspendable
import co.paralleluniverse.kotlin.fiber

fun main(args: Array<String>) {
    val f1 = fiber @Suspendable {
        (1..3).forEach {
            println("fiber name f1, current value: ${it}")
            Fiber.sleep(1000)
        }
        "f1 all done"
    }

    val f2 = fiber @Suspendable {
        (1..3).forEach {
            println("fiber name f2, current value: ${it}")
            Fiber.sleep(1000)
        }
        "f2 all done"
    }
    println(f1.get())
    println(f2.get())
}
doctorpangloss commented 5 years ago

I haven't run the code, so take this with a grain of salt (i.e, it may be totally wrong).

But I think the reason the first example exits is very simple. You reach the end of the main thread, and your application exits. The fiber isn't its own thread. If you created a new thread, then joined the fiber inside of it, and didn't join the new thread in your main method, everything would work.

You can see a similar issue here: https://stackoverflow.com/questions/52196187/what-happen-with-coroutines-when-main-thread-exits