Home > Net >  How to use actors to handle message frequently in a single thread?
How to use actors to handle message frequently in a single thread?

Time:05-26

I need to launch some code frequently in a single non-UI thread. I am trying to use actors to achieve it:

class SomeClass {

    @OptIn(ObsoleteCoroutinesApi::class)
    private fun CoroutineScope.myActor() = actor<MyMessage> {
        for (message in channel) {
            delay(5000)
            Log.d("SomeClass", "Message ${Thread.currentThread().name}")
        }
    }

    private var channel: SendChannel<MyMessage>? = null
    private val scope = CoroutineScope(Dispatchers.Default)

    fun send() {
        scope.launch {
                if (channel == null) {
                    channel = myActor()
                }
                channel?.send(IncCounter)
            }
    }

    sealed class MyMessage
}

And then calling it:

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState)

    val c = SomeClass()
    c.send()
    c.send()
    c.send()
    c.send()       

}

Output:

Message DefaultDispatcher-worker-8
Message DefaultDispatcher-worker-2
Message DefaultDispatcher-worker-8
Message DefaultDispatcher-worker-2

So, as I see it creates more than one thread. How to implement frequently messaging handling in a single thread?

CodePudding user response:

Try to use limitedParallelism(1) function on CoroutineDispatcher:

private val scope = CoroutineScope(Dispatchers.Default.limitedParallelism(1))

OR

private fun CoroutineScope.myActor() = actor<MyMessage>(context = Dispatchers.Default.limitedParallelism(1)) { ... }
  • Related