Kotlin中的异步预定作业

时间:2019-02-24 14:21:15

标签: asynchronous kotlin quartz-scheduler

我试图了解哪种方法是在Kotlin中按计划的速率启动异步作业的最佳方法,而应用程序通常正在运行它的正常任务。假设我有一个简单的应用程序,该应用程序每秒仅打印“ ...”,但是每5秒我要另一个作业/线程/协程(最适合)打印“您有消息!”。对于异步作业,我有一个NotificationProducer类,它看起来像这样。

class NotificationProducer {

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

然后,我的主要方法如下。

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

我应该使用GlobalScope.asyncTimer().schedule(...)还是某些Quartz作业来实现我想要的?任何建议都将受到高度赞赏。关键是通知必须来自另一个类(例如NotificationProducer)

2 个答案:

答案 0 :(得分:0)

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

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 :(得分:0)

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

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)
    }
}