Kotlin的异步预定工作

问题描述 投票:0回答:2

我试图了解哪个是在Kotlin中以预定速率触发异步作业的最佳方法,而应用程序通常正在运行它的正常任务。假设我有一个简单的应用程序,每秒只打印出“......”,但是每5秒我想要另一个作业/线程/协同程序(它们最适合)打印“你有消息!”。对于异步工作,我有一个类NotificationProducer,它看起来像这样。

class NotificationProducer {

    fun produce() {
        println("You have a message!")
    }
} 

然后,我的主要方法看起来像这样。

    while (true) {
        println("...")
        sleep(1000)
    }

我应该使用GlobalScope.asyncTimer().schedule(...)或一些Quartz工作来实现我想要的吗?任何建议都非常感谢。关键是通知必须来自另一个类(例如NotificationProducer)

asynchronous kotlin quartz-scheduler
2个回答
1
投票

如果我正确理解了这个问题,使用Kotlin协程可以实现如下:

class Presenter : CoroutineScope { // implement CoroutineScope to create local scope
    private var job: Job = Job()
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Default + job 

    // this method will help to stop execution of a coroutine. 
    // Call it to cancel coroutine and to break the while loop defined in the coroutine below    
    fun cancel() {
        job.cancel()
    }

    fun schedule() = launch { // launching the coroutine
        var seconds = 1
        val producer = NotificationProducer()
        while (true) {
            println("...")
            delay(1000)

            if (seconds++ == 5) {
                producer.produce()
                seconds = 1
            }
        }
    }
}

然后你可以使用Presenter类的一个实例启动协程并停止它:

val presenter = Presenter()
presenter.schedule() // calling `schedule()` function launches the coroutine

//...

presenter.cancel() // cancel the coroutine when you need

1
投票

对于简单的调度要求,我使用协同程序实现它,因为它很有趣:

class NotificationProducerScheduler(val service: NotificationProducer, val interval: Long, val initialDelay: Long?) :
    CoroutineScope {
    private val job = Job()

    private val singleThreadExecutor = Executors.newSingleThreadExecutor()

    override val coroutineContext: CoroutineContext
        get() = job + singleThreadExecutor.asCoroutineDispatcher()


    fun stop() {
        job.cancel()
        singleThreadExecutor.shutdown()
    }

    fun start() = launch {
        initialDelay?.let {
            delay(it)
        }
        while (isActive) {
            service.produce()
            delay(interval)
        }
        println("coroutine done")
    }
}

否则,Java并发API也非常可靠:

class NotificationProducerSchedulerJavaScheduler(
    val service: NotificationProducer,
    val interval: Long,
    val initialDelay: Long = 0
) {

    private val scheduler = Executors.newScheduledThreadPool(1)
    private val task = Runnable { service.produce() }

    fun stop() {
        scheduler.shutdown()
    }

    fun start() {
        scheduler.scheduleWithFixedDelay(task, initialDelay, interval, TimeUnit.MILLISECONDS)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.