我在这里做了一些搜索并找不到答案,所以我觉得最好问一下。 我在一个简单的Java swing应用程序中运行了一点点昂贵的算法。让我来描述一下结构:
在我的JPanel
run()
方法中:
public void run() {
while(true) {
Algorithm alg = new Algorithm(signal);
new Thread(alg).start();
//Wait for algorithm to finish
signal.await(alg);
updateInterface();
Thread.sleep(60L);
}
}
算法循环遍历.JPG文件的像素,然后遍历另一个大的整数数组(长度~12000)并返回。没有额外昂贵的计算方法。我也在算法Thread.sleep(60L)
方法中调用run()
。
udpateInterface()
方法非常快,只需绘制一些java.awt.Polygon
个对象。
即使我正在呼叫Thread.sleep(60L)
,我的Mac Book(2.4 GHz Intel Core 2 Duo,Mem 4GB 1067)的CPU使用率约为160%。
有没有办法在不熔化电脑的情况下运行它?我正在使用CountDownLatch
等待通知机制。
谢谢!
答案 0 :(得分:4)
我会使用以下模式来安排重复任务。
private ScheduledExecutorService executorService = null;
public void start() {
if (executorService != null && !executorService.isShutdown()) return;
executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
Algorithm alg = new Algorithm(signal);
alg.run();
updateInterface();
}
}, 0, 60, TimeUnit.MILLISECONDS);
}
public void stop() {
if (executorService != null)
executorService.shutdown();
}
答案 1 :(得分:2)
160%的CPU使用率相对于计算机的单个核心 - 也就是说,您机器上的最大可能性为200%,因为它有两个核心。你没有融化你的处理器。
答案 2 :(得分:2)
如果之后要做的就是让当前线程等待另一个线程完成,那么启动另一个线程是没有意义的。您也可以在已有的线程中运行算法;无论哪种方式,在算法完成之前,您都不会进入updateInterface()
。
正如其他人所指出的那样,在算法完成并更新UI之后,您只需要等待60毫秒才能再次启动算法。听起来你的程序大部分时间都在运行算法。如果您需要快速更新屏幕,那就没关系,但您可能会考虑使用更长的延迟。
此外,每次循环时都会启动一个新线程。该线程是运行算法一次然后终止,还是在循环中运行算法?如果您有一个循环启动线程,每个线程都是长时间运行的CPU密集型循环,您可能会意外地同时运行该算法的许多副本。如果您希望算法线程在发出信号后终止,则应join()
确认它。
答案 3 :(得分:1)
你想要多久等待?如果你想等待60秒,你应该使用60000L,因为时间以毫秒为单位。