Creating an actor

Say that we need to modify a counter safely from many different threads. First, let's create a new class. In that class, we can have a private counter and a private single-thread dispatcher, with a function to retrieve the current value of the counter:

private var counter = 0
private val context = newSingleThreadContext("counterActor")

fun getCounter() = counter

Now that we have encapsulated the value of the counter, we simply need to add an actor that will increase the value upon each received message:

val actorCounter = actor<Void?>(context) {
for (msg in channel
) {
counter++
}
}

Because we don't actually use the message being sent, we can simply set the type of the actor to Void?, so that the caller can send null. Now we can update our main function to use this actor:

fun main(args: Array<String>) = runBlocking {
val workerA = asyncIncrement(2000)
val workerB = asyncIncrement(100)

workerA.await()
workerB.await()

print("counter [${getCounter()}]")
}
fun asyncIncrement(by: Int) = async(CommonPool) {
for (i in 0 until by) {
actorCounter.send(null)
}
}
Notice that asyncIncement() is using CommonPool as its context.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.213.212