Añadir un sueño para poner el hilo en inactivo durante algún intervalo:
Thread.sleep
Sin tener un sueño, el bucle while se consumen todos los recursos de computación que está disponible. (. Por ejemplo, en teoría, de 100% en un sistema de un solo núcleo, o 50% en un doble núcleo, y así sucesivamente)
Por ejemplo, el siguiente ciclo una vez a través de un bucle while
aproximadamente cada 50 milisegundos:
while (true)
{
try
{
Thread.sleep(50);
}
catch (Exception e)
{
e.printStackTrace();
}
}
Esto debería reducir un poco la utilización de la CPU.
Con un sueño en el ciclo, el sistema operativo también dará suficiente tiempo al sistema para que otros procesos y subprocesos hagan sus cosas, por lo que el sistema también responderá. Ya en la época de los sistemas de núcleo único y los sistemas operativos con programadores no tan buenos, los bucles como este podrían haber hecho que el sistema no respondiera.
Dado que el tema de la utilización de while
bucles para un juego subió, si el juego va a implicar una interfaz gráfica de usuario, el bucle de juego debe estar en un hilo separado o bien la interfaz gráfica de usuario en sí dejará de responder.
Si el programa va a ser un juego basado en consola, entonces el enhebrado no será un problema, pero con las interfaces gráficas de usuario que están basadas en eventos, tener un bucle de larga vida en el código hará que el GUI no responde.
Enhebrar y tales son áreas de programación bastante complicadas, especialmente al comenzar, por lo que sugiero que se plantee otra pregunta cuando sea necesario.
El siguiente es un ejemplo de una aplicación Swing basada en un JFrame
que actualiza un JLabel
que contendrá el valor devuelto desde System.currentTimeMillis
. El proceso de actualización se lleva a cabo en un subproceso separado, y un botón "Detener" detendrá el subproceso de actualización.
Pocos conceptos del ejemplo ilustrará:
- Una aplicación de interfaz gráfica de usuario basada en Swing con un hilo separado para actualizar el tiempo - esto evitará composición final de la rosca interfaz gráfica de usuario. (Llamado EDT, o subproceso de envío de eventos en Swing).
- Tiene el bucle
while
con una condición de bucle que no es true
, pero se sustituye por boolean
que determinará si se debe mantener el bucle con vida.
- Cómo
Thread.sleep
factores en una aplicación real.
Por favor, discúlpeme para el largo ejemplo:
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();
}
});
}
}
Algunos recursos sobre el roscado y el uso de swing:
@William: Por favor, lea la respuesta de Mystere Man: es el enfoque más correcto, a pesar de la respuesta aceptada altamente votada. Deberías basar tu juego en un temporizador de velocidad de fotogramas no en un bucle de CPU. –
Además, recomendaría cambiar la respuesta aceptada. –