如何停止Java while循环占用超过50%的CPU? [英] How can I stop a Java while loop from eating >50% of my CPU?
问题描述
好的,我在一个空程序上进行了测试,仅运行一会儿(true){}就使我的CPU占用了50%以上的内存.我正在开发一个游戏,该游戏使用while循环作为主循环,并且CPU始终处于100.
Okay, I tested this on an empty program, and just having a while(true){} running gave me >50% on my CPU. I have a game I'm working on that uses a while loop as it's main loop, and it's CPU is at 100 all the time.
如何让Java一遍又一遍地重复某件事,而又不会消耗我50%以上的CPU来做重复呢?
How can I get Java to repeat something over and over without eating up >50% of my CPU just to do the repeating?
推荐答案
添加睡眠以使线程在一段时间内处于空闲状态:
Add a sleep to put the thread into idle for some interval:
没有睡眠,while循环将消耗所有可用的计算资源. (例如,理论上,单核系统为100%,双核系统为50%,依此类推.)
Without having a sleep, the while loop will consume all the computing resources that is available. (For example, theoretically, 100% in a single core system, or 50% in a dual core, and so on.)
例如,以下内容将大约每50毫秒通过while
循环循环一次:
For example, the following will cycle once through a while
loop approximately every 50 milliseconds:
while (true)
{
try
{
Thread.sleep(50);
}
catch (Exception e)
{
e.printStackTrace();
}
}
这应该会大大降低CPU利用率.
This should bring down the CPU utilization quite a bit.
在循环中休眠之后,操作系统还将为其他线程和进程提供足够的系统时间来执行其任务,因此系统也将做出响应.在单核系统和具有不太好的调度程序的操作系统的时代,像这样的循环可能会使系统反应迟钝.
With a sleep in the loop, the operating system will also give enough system time for other threads and processes to do their things, so the system will be responsive as well. Back in the days of single core systems and operating systems with not-so-good schedulers, loops like this could have made the system very unresponsive.
由于出现了在游戏中使用while
循环的主题,因此,如果游戏要包含GUI,则游戏循环必须位于单独的线程中,否则GUI本身将无响应.
Since the topic of use of while
loops for a game came up, if the game is going to involve a GUI, the game loop must be in a separate thread or else the GUI itself will become unresponsive.
如果该程序将是一个基于控制台的游戏,那么线程化将不再是问题,而是使用事件驱动的图形用户界面,该代码中存在长寿命的循环将使该GUI成为可能.没有反应.
If the program is going to be a console-based game, then threading is not going to be an issue, but with graphical user interfaces which are event-driven, having a long-living loop in the code will make the GUI unresponsive.
线程等是编程中非常棘手的领域,尤其是在入门时,所以我建议在必要时提出另一个问题.
Threading and such are pretty tricky areas of programming, especially when getting started, so I suggest that another question be raised when it becomes necessary.
以下是基于JFrame
的Swing应用程序的示例,该应用程序更新了JLabel
,该JLabel
将包含从System.currentTimeMillis
返回的值.更新过程在单独的线程中进行,并且停止"按钮将停止更新线程.
The following is an example of a Swing application based in a JFrame
which updates a JLabel
that will contain the returned value from System.currentTimeMillis
. The updating process takes place in a separate thread, and a "Stop" button will stop the update thread.
该示例将说明一些概念:
Few concepts the example will illustrate:
- 基于Swing的GUI应用程序,具有单独的线程来更新时间-这将防止GUI线程锁定. (在Ewing中称为EDT或事件调度线程.)
- 使
while
循环的循环条件不是true
,而是用boolean
代替,这将确定是否使循环保持活动状态. -
Thread.sleep
如何纳入实际应用.
- A Swing-based GUI application with a separate thread to update time -- This will prevent lock up of the GUI thread. (Called the EDT, or event dispatch thread in Swing.)
- Having the
while
loop with a loop condition that is nottrue
, but substituted with aboolean
which will determine whether to keep the loop alive. - How
Thread.sleep
factors into an actual application.
请原谅我的例子:
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的一些资源:
Some resources about threading and using Swing:
- Threads and Swing
- Lesson: Concurrency
这篇关于如何停止Java while循环占用超过50%的CPU?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!