Java - Hilos Thread JFrame


Crear y arrancar el hilo desde una clase que extiende jframe y que implemente Runanble

Para crear un hilo en java, primero debemos hacer una clase que implemente la interface Runnable  y además extienda la interfaz  JFrame  
Crear un nuevo proyecto, agregar un jframe, dentro del jframe un jpanel, en el jpanel agregar dos botones, uno para salir y el otro para lanzar el hilo
La interfaz quedará de la siguiente manera:

package ThreadJFrame;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author neo
*/
public class Principal extends javax.swing.JFrame implements Runnable{
boolean seguirHilo=false;
boolean hiloIniciado=false;
Thread hilo;
int cont=0;
/**
* Creates new form Principal
*/
public Principal() {
initComponents();
}

private void jbLanzarHiloActionPerformed(java.awt.event.ActionEvent evt) {
iniciarHilo();
if(seguirHilo){
pararHIlo(false);
jbLanzarHilo.setText("Reanudar hilo");
}else{
pararHIlo(true);
jbLanzarHilo.setText("Detener hilo");
}
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
System.exit(0);
}

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Principal().setVisible(true);
}
});
}
/*método para iniciar el hilo*/
public void iniciarHilo(){
hilo=new Thread(this);
hilo.start();
hiloIniciado=true;
}
/*método para parar el hilo*/
public void pararHIlo(boolean estado){
seguirHilo=estado;
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JLabel jLabel1;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextArea jTextArea1;
private javax.swing.JButton jbLanzarHilo;
// End of variables declaration

@Override
public void run() {
/*aquí va el código que se ejecutará en el hilo*/
while(seguirHilo){
System.out.println(cont+" :Hola mundo desde java usando hilos");
cont++;
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
Logger.getLogger(Principal.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Lo que esté en el método run() es lo que se ejecutará en un hilo separado.
Cuando queramos que empiece a ejecutarse, creamos una instancia de la clase Thread pasándole una instancia de MiRunnable y la arrancamos
public void iniciarHilo(){
hilo=new Thread(this);
hilo.start();
hiloIniciado=true;
}

Dormir un hilo

Para dormir un hilo durante un cierto tiempo, basta con llamar al método sleep(). Puesto que este método lanza una excepción, debemos capturarla.
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
Logger.getLogger(Principal.class.getName()).log(Level.SEVERE, null, ex);
}

Terminar un hilo

Es bastante habitual hacer que un hilo se meta en un bucle infinito, realizando una tarea indefinidamente, pero también podemos hacer el ciclo continúe o se pare dependiendo de una variable específica.
@Override
public void run() {
/*aquí va el código que se ejecutará en el hilo*/
while(seguirHilo){
System.out.println(cont+" :Hola mundo desde java usando hilos");
cont++;
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
Logger.getLogger(Principal.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Si queremos que este hilo termine y buscamos en la API de java, vemos que todos los métodos para detener hilos (Thread.destroy()Thread.suspend(), etc) están obsoletos, desaconsejados, etc.
¿Cómo terminamos entonces el hilo?
La forma que habitualmente implemento, es poner una variable booleana que indica si el hilo debe terminarse y usarla en el while.
@Override
public void run() {
/*aquí va el código que se ejecutará en el hilo*/
while(seguirHilo){
System.out.println(cont+" :Hola mundo desde java usando hilos");
cont++;
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
Logger.getLogger(Principal.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
De esta forma, para terminar el hilo de forma segura, bastará con llamar al método pararHIlo(false);
public void pararHIlo(boolean estado){
seguirHilo=estado;
}

Comentarios:

@