Java线程和高CPU使用率

时间:2012-03-15 04:55:52

标签: java multithreading swing cpu-usage

我在这里做了一些搜索并找不到答案,所以我觉得最好问一下。 我在一个简单的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 等待通知机制。

谢谢!

4 个答案:

答案 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,因为时间以毫秒为单位。