Aggiungi un sonno di mettere il filo nella inattivo per un certo intervallo di:
Thread.sleep
Senza avere un sonno, il ciclo while consumerà tutte le risorse di calcolo che è disponibile. (. Ad esempio, teoricamente, 100% in un singolo sistema centrale, o il 50% in un dual core, e così via)
Per esempio, il seguente ciclo una volta attraverso un ciclo while
circa ogni 50 millisecondi:
while (true)
{
try
{
Thread.sleep(50);
}
catch (Exception e)
{
e.printStackTrace();
}
}
Ciò dovrebbe ridurre l'utilizzo della CPU piuttosto un po '.
Con una sospensione nel ciclo, il sistema operativo fornirà anche abbastanza tempo di sistema per altri thread e processi per fare le loro cose, quindi anche il sistema sarà reattivo. Ai tempi dei sistemi single core e dei sistemi operativi con scheduler non-così-buoni, cicli come questo avrebbero potuto rendere il sistema molto insensibile.
Dal momento che il tema di utilizzo di while
anelli per un gioco si avvicinò, se il gioco sta per coinvolgere una GUI, il ciclo di gioco deve essere in un thread separato oppure la GUI stesso sarà non rispondere.
Se il programma sarà un gioco basato su console, il threading non sarà un problema, ma con interfacce utente grafiche gestite da eventi, con un ciclo di lunga durata nel codice renderà il GUI non risponde.
Il threading e simili sono aree di programmazione piuttosto complicate, soprattutto quando si inizia, quindi suggerisco di sollevare un'altra domanda quando è necessario.
Di seguito è riportato un esempio di un'applicazione Swing basata su JFrame
che aggiorna uno JLabel
che conterrà il valore restituito da System.currentTimeMillis
. Il processo di aggiornamento avviene in un thread separato e un pulsante "Stop" interromperà il thread di aggiornamento.
Pochi concetti l'esempio chiarirà:
- Un'applicazione GUI Swing-based con un thread separato per aggiornare il tempo - Questo consentirà di evitare lock up del thread GUI. (Chiamato EDT, o thread di invio evento in Swing.)
- Avere il ciclo
while
con una condizione di loop che non è true
, ma sostituito con uno boolean
che determinerà se mantenere il ciclo attivo.
- Come i fattori
Thread.sleep
in un'applicazione effettiva.
Ti prego di scusarmi per il lungo esempio
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();
}
});
}
}
Alcune risorse sulla filettatura e con swing:
@William: Si prega di leggere la risposta di Mystere Man - è l'approccio più corretto, nonostante la risposta accettata in grande cambiamento. Dovresti basare il tuo gioco su un timer frame-rate e non su un loop CPU. –
Inoltre, vorrei incoraggiare a cambiare la risposta accettata. –