如何建立一个无限循环的显示器?

时间:2018-10-18 15:04:27

标签: performance kotlin monitor

我正在Kotlin中建立一个监视器来调度某些操作,我想要的是一个在给定时间间隔内插入或更新一些数据库条目的程序。到目前为止,我得到的是一个可以在给定时间范围内运行的程序,但是在我的porgram中有一个无限循环,当不需要更新时,它会占用多达30%的处理器能力。所以我的问题是如何构建一个没有无限循环的监视器?

到目前为止,这是我的代码:

    while(!operations.done && appConfigurations.run_with_monitor) {
    if (DataSourceMonitor.isReadyForUpdate(lastMonitorModel)) {
        operations.update()
    }
}

操作是要执行的不同动作的完整序列。每个操作都实现了IScheduler接口。

interface IScheduler {
var done: Boolean
fun update()
fun reset()

}

实施示例:

class Repeat(private val task: IScheduler) : IScheduler {
override var done = false

override fun update() {
    if (this.task.done) {
        this.reset()
    }
    this.task.update()
    //logger.info { "Update repeat, done is always $done" }
}

override fun reset() {
    this.task.reset()
    this.done = false
}
}

class Sequence(private val task1: IScheduler, private val task2: IScheduler): IScheduler {
override var done = false
var current = task1
var next = task2

override fun update() {
    if (!this.done) {
        this.current.update()
        if (this.current.done) {
            this.current = this.next
        }
        if (this.next.done) {
            this.done = true
        }
    }
}

class Print(private val msg: String): IScheduler {
override var done = false

override fun update() {
    println(this.msg)
    this.done = true
}

override fun reset() {
    this.done = false
}

}

操作值可以如下:

val operations = Repeat(Sequence(Print("First action"), Print("Another action")))

**所以现在我的监视器可以正常工作并且可以正常工作,但是如何改善无限循环的性能呢? **

希望任何人对此都有一些想法。

2 个答案:

答案 0 :(得分:0)

如果您的DataSourceMonitorisReadyForUpdate返回true之前没有阻塞,那么通常的方法是增加延迟。例如:

while(!operations.done && appConfigurations.run_with_monitor) {
    if (DataSourceMonitor.isReadyForUpdate(lastMonitorModel)) {
        operations.update()
    } else {
        Thread.sleep(POLL_DELAY);
    }
}

如果它始终准备好进行更新,则不会有任何延迟,但是如果它尚未准备好进行更新,则它将休眠。您需要调整POLL_DELAY。值越大,意味着CPU使用率越低,但是在检测到要处理的新事件时,延迟就越大。较小的值产生较少的延迟,但使用更多的CPU。

如果您真的想花哨的话,可以将轮询延迟从较小的值开始,然后增加到某个最大值,一旦发现事件,则将其降低。这可能是矫kill过正,但是如果您有兴趣的话,请查找“自适应轮询”。

答案 1 :(得分:0)

我已经重构了代码,并且可以通过抽象类TimerTask删除IScheduler接口,以更少的代码来实现相同的结果。可以使用以下代码行完成此工作:

    val scheduler = Sequence(
        Print("Executed task 1"),
        Sequence(Print("Executed task 2"),
                Sequence(Print("Executed task 3"), Print("Finished Scheduler")))
)


Timer().schedule(scheduler, DELAY, PERIOD)

所有接口实现都更改为TimerTask实现:

class Print(private val msg: String): TimerTask() {
override fun run() {
    println(msg)
 }
}

class Sequence(private val task1: Runnable, private val task2: Runnable): TimerTask() {
override fun run() {
    task1.run()
    task2.run()
 }
}