当前位置: 首页 > 面试题库 >

如何停止Java while循环消耗超过50%的CPU?

东郭凯捷
2023-03-14
问题内容

好的,我在一个空程序上进行了测试,仅运行一会儿(true){}就使我的CPU占用了50%以上的资源。我正在开发一个游戏,它使用while循环作为主循环,并且CPU始终处于100。

我如何才能让Java重复执行某些操作,而又不消耗超过50%的CPU来执行重复操作呢?


问题答案:

添加睡眠以使线程在一段时间内处于空闲状态:

Thread.sleep

没有睡眠,while循环将消耗所有可用的计算资源。(例如,理论上,单核系统为100%,双核系统为50%,依此类推。)

例如,以下代码将while大约每50毫秒循环一次:

while (true)
{
    try
    {
        Thread.sleep(50);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

这将大大降低CPU利用率。

有了一个休眠循环,操作系统还将为其他线程和进程提供足够的系统时间来执行其任务,因此系统也将做出响应。在单核系统和具有不太好的调度程序的操作系统的时代,像这样的循环可能会使系统反应迟钝。

由于出现了while针对游戏使用循环的主题,因此,如果游戏要包含GUI,则游戏循环必须位于单独的线程中,否则GUI本身将无响应。

如果该程序将是一个基于控制台的游戏,那么线程就不会成为问题,而是使用事件驱动的图形用户界面,如果代码中存在长时间循环,将使GUI无响应。

线程等是编程中非常棘手的领域,尤其是在入门时,因此我建议在必要时提出另一个问题。

以下是基于的Swing应用程序的示例,该应用程序JFrame更新JLabel,其中将包含的返回值System.currentTimeMillis。更新过程在单独的线程中进行,并且“停止”按钮将停止更新线程。

该示例将说明一些概念:

  • 一个基于Swing的GUI应用程序,具有单独的线程来更新时间-这将防止GUI线程被锁定。(在Ewing中称为EDT或事件调度线程。)
  • 使while循环的条件不是true,而是用代替,boolean这将确定是否使循环保持活动状态。
  • 如何将Thread.sleep因素纳入实际应用。

请原谅我的例子:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TimeUpdate
{
    public void makeGUI()
    {
        final JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JLabel l = new JLabel();

        class UpdateThread implements Runnable
        {
            // Boolean used to keep the update loop alive.
            boolean running = true;

            public void run()
            {
                // Typically want to have a way to get out of
                // a loop. Setting running to false will 
                // stop the loop.
                while (running)
                {
                    try
                    {
                        l.setText("Time: " +
                                System.currentTimeMillis());

                        Thread.sleep(50);
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }

                // Once the run method exits, this thread
                // will terminate.
            }
        }

        // Start a new time update thread.
        final UpdateThread t = new UpdateThread();
        new Thread(t).start();

        final JButton b = new JButton("Stop");
        b.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e)
            {
                t.running = false;
            }
        });

        // Prepare the frame.
        f.getContentPane().setLayout(new BorderLayout());
        f.getContentPane().add(l, BorderLayout.CENTER);
        f.getContentPane().add(b, BorderLayout.SOUTH);
        f.setLocation(100, 100);
        f.pack();
        f.setVisible(true);
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new TimeUpdate().makeGUI();
            }
        });
    }
}

有关线程和使用Swing的一些资源:

  • 线程和摆动
  • 课程:并发


 类似资料:
  • 问题内容: 我正在编写代码以确定nxn列表中的每个元素是否相同。即返回true,但将返回false。我正在考虑编写一个代码,当它发现与第一个元素不同的元素时立即停止。即: 我想停止此循环, 然后返回false。否则返回true。我将如何实施呢? 问题答案: 使用和为此。可以使用以下命令在Python中完成打破嵌套循环的操作: 另一种方法是将所有内容包装在函数中,并用于从循环中退出。

  • 问题内容: 我试图用图像精灵建立一个加载指示器,然后我想到了这个功能 所以输出看起来像这样 我不得不使用setBgPosition(); 在其他内部保持循环运行,所以现在我的问题是一旦我想要[加载完成],如何停止该循环? 问题答案: 返回计时器句柄,您可以使用该句柄停止超时。 因此,例如: 因此,您可以将其用作: 请注意,我没有将其再次调用,而是将其重新设置为。否则,这将行不通。另请注意,我已将超

  • 我有一个家庭作业。。。代码如下。。。有几个问题要问。。。提前谢谢。Java初学者。。。如果这看起来很笨拙,请不要笑 有没有办法对我问的每个问题使用我的IF语句,而不必为每个问题更改字符串名称? 有没有办法创建一个方法(?)对于那些如果语句,所以我不必为我问的每一个问题写出来? 如果用户在10秒内没有输入答案,我想有一个定时器提示他们回答,我该怎么做?

  • 我是java的新手,我正在编写这个简短的程序,您可以在其中猜测1到10之间的数字。正确的数字存储为整数。如果您猜测较低的数字,它应该说“正确的数字较高”,如果您猜测较高,它应该说“正确的数字较低”。这是我所拥有的: 所以很明显这是行不通的,因为如果你输入一个更小的数字,它会跳到下一个数字,即使这个数字更大,它也是正确的。那么,我如何解决这个问题,让它检查两个语句呢?抱歉解释得不好。谢了。

  • 我有一个程序,它每秒钟响一次,直到停止。问题是,在我按下“开始”并发出嘟嘟声后,我无法单击“停止”按钮,因为窗口冻结。欢迎任何帮助。

  • 我正在尝试创建一个自动打开我的在线类的脚本。我写了这样的代码: 现在,问题是第一个if语句被无休止地执行,我想让它只执行一次,而不是等到现在==lesson2再执行第二个if etc