【问题标题】:Java Threads and high cpu usageJava 线程和高 CPU 使用率
【发布时间】:2012-03-15 04:55:52
【问题描述】:

我在这里做了一些搜索,但找不到答案,所以我认为最好问一下。 我在一个简单的 Java swing 应用程序中运行了一些昂贵的算法。让我描述一下结构:

在我的JPanelrun()方法中:

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)并返回。没有额外昂贵的计算槽。我也在算法run() 方法中调用Thread.sleep(60L)

udpateInterface() 方法很快,只需画一些java.awt.Polygon 对象即可。

即使我打电话给Thread.sleep(60L),我的 Mac Book(2.4 GHz Intel Core 2 Duo,Mem 4GB 1067)上的 CPU 使用率约为 160%。

有没有一种方法可以在不熔化我的计算机的情况下运行它?我使用CountDownLatch 作为 等待通知机制。

谢谢!

【问题讨论】:

  • Thread.sleep 正在影响父线程(显示 while 的那个),而不是 new 线程 (new Thread)... 代码实际上可能一次生成多个线程,具体取决于signal 和所有线程。
  • 是的,但是算法线程也有睡眠调用。
  • 我不明白sleep 调用的目的是什么。如果你有工作要做,你为什么要睡觉”?你是什么意思“融化我的电脑?!工作不能融化你的电脑。计算机的目的是工作。如果你有有用的工作要做,让 CPU 去做。这就是他们的目的。
  • @pst:换句话说,他们的能力被浪费了。信封的顶部在那里,因此他们可以非常快速地完成大量工作。如果您效率低下或浪费 CPU,那是一回事。但如果你有有用的工作要做,你希望 CPU 尽快完成。
  • 如果您担心 CPU 负载,您应该找出导致高负载的原因。看起来这是你的算法。那么你想怎么做呢?不运行?

标签: java multithreading swing cpu-usage


【解决方案1】:

我会使用以下模式来安排重复任务。

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

【讨论】:

    【解决方案2】:

    160% 的 CPU 使用率是相对于您机器的一个单个 核心而言的——也就是说,您的机器上可能的最大值是 200%,因为它有两个核心。你没有融化你的处理器。

    【讨论】:

    • 感谢您的评论。有时它会非常接近 200%,我不知道这是否会损坏计算机...
    • 没有。这是完全正常的——事实上,200% 的使用率是一个信号,表明您的应用程序正在有效地并行化工作。
    • @LouisWasserman 或者有效地浪费能源 ;-) 让 CPU 保持忙碌并不等同于让它们保持高效......无论如何,我同意 CPU 有 something i> 去做,这不一定是坏事。然而,问题仍然存在:如何在解决这个问题的同时让它们“工作更少”(花费更长的时间)?
    • 除非电脑有什么大毛病,否则你不能给它做计算工作来损坏它。
    • @pst:用户说“我真的希望我的 CPU 更空闲”与律师说“我很高兴我的客户与警方交谈”一样普遍。它只是不会发生。如果有工作要做,你希望你的电脑来做。
    【解决方案3】:

    如果你之后要做的就是让当前线程等待另一个线程完成,那么启动另一个线程是没有意义的。您不妨在已有的线程中运行算法;无论哪种方式,在算法完成之前,您都不会继续使用updateInterface()

    正如其他人指出的那样,在算法完成并更新 UI 后,您只需等待 60 毫秒即可再次启动算法。听起来您的程序大部分时间都在运行算法。如果您需要它来快速更新屏幕,那很好,但您可能会考虑使用更长的延迟。

    此外,您每次通过循环都会启动一个新线程。该线程是运行一次算法然后终止,还是循环运行算法?如果您有一个循环启动线程,每个线程都是长时间运行的 CPU 密集型循环,您可能会不小心一次运行该算法的多个副本。如果您希望算法线程在向您发出信号后终止,您应该join() 确认。

    【讨论】:

    • 线程运行算法并完成。我已经尝试在同一个线程中运行,它增加了 cpu 使用率。同步没问题,我需要重新设计这个。谢谢!
    【解决方案4】:

    你要等多久?如果要等待 60 秒,则应使用 60000L,因为时间以毫秒为单位。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多