我的程序需要定期检查的事项列表 - 当状态发生变化时,不能分配任何事件来触发。这些的东西作为Robot类实例存储在数组列表中:
public class RobotManager extends Thread {
protected final List<Robot> robots = new ArrayList<>();
}
每个机器人都有canRun
任务,如果有机器人可以做的话,它会返回true。这包括更新GUI按钮的可用性等。
我目前的计划是睡眠一段时间,比如800毫秒,然后循环浏览列表和canRun
(最终start()
)列表中的每个Robot
。但这似乎并不是很好 - 如果有足够数量的任务,程序将每800毫秒滞后一次。如果该计划可以更好:
sleep
800毫秒左右的东西,精度较低,并尝试在有备用资源的地方运行sleep
以减少所需资源的峰值。换句话说:在Java中,我可以使sleep
不那么精确,有利于在系统有备用资源时运行吗?
答案 0 :(得分:0)
我认为您正在寻找Thread.yield()
方法。
的Javadoc:
A hint to the scheduler that the current thread is willing to yield
its current use of a processor. The scheduler is free to ignore this
hint.
Yield is a heuristic attempt to improve relative progression
between threads that would otherwise over-utilise a CPU. Its use
should be combined with detailed profiling and benchmarking to
ensure that it actually has the desired effect.
It is rarely appropriate to use this method. It may be useful
for debugging or testing purposes, where it may help to reproduce
bugs due to race conditions. It may also be useful when designing
concurrency control constructs such as the ones in the
java.util.concurrent.locks package.
结合使用sleep(...)
和yield()
,你可以找到“机器人列表不经常处理”和“它正在吃掉很多cpu”之间的权衡。您睡觉的时间和产量调用次数(在机器人内和/或机器人调用之间)取决于机器人实际执行的操作。
答案 1 :(得分:0)
您应该将进程/线程优先级设置为空闲或极低优先级。只有在没有其他具有更高优先级的任务准备好运行时,才会调度具有空闲优先级的线程/进程。请注意,如果当前计算机非常繁忙,则空闲线程根本不会运行,这会打开饥饿的可能性。低优先级线程仍然可以让您获得一些时间片,只是它首先会产生更高优先级的线程。线程优先级的具体行为取决于JVM实现和操作系统,但通常如果优先级较高的线程准备好运行,则优先级较低的线程可能会被抢占,如果优先级较高的线程则不太可能被调度准备好了。
另一个评论是,我建议避免轮询可用任务,而是使用BlockingQueue代替ArrayList并休眠。如果您的主题正在等待BlockingQueue,那么它将无法安排,直到队列中出现某些内容,因此您不会进行不可预测的唤醒检查。它对机器来说也更好,因为被阻塞的线程会让CPU进入低功耗模式(不像一个不断唤醒的线程,它会让CPU保持在脚趾上),如果你的程序运行在一个程序上,这一点很重要。带电池的机器。