Hilos en Java
Un hilo de ejecución (también llamado hebra o subproceso) es la unidad más pequeña que el sistema puede procesar y planificar.
Cuando tenemos varios hilos en una aplicación, esta puede realizar varias tareas al mismo tiempo de forma concurrente. Todos los hilos de una aplicación comparten recursos. Dichos recursos pueden ser los archivos abiertos, espacio de memoria, etc.
Al poder realizar una aplicación varias funciones de forma simultánea el diseño de la misma se suele simplificar.
Al compartir los recursos de una aplicación, cualquier hilo puede modificarlos y de esa manera esas modificaciones son válidas para el resto de hilos. Si un hilo modifica cualquier dato en memoria los demás hilos podrán acceder a dicho dato modificado de forma inmediata.
Obviamente cada hilo tiene como propios su contador de programa, la pila de ejecución y el estado de la CPU (en caso contrario no podría funcionar de forma independiente).
Diferencias entre hilos y procesos
Los procesos son independientes mientras que los hilos de un proceso comparten recursos de forma directa.
Muchos sistemas operativos ofrecen facilidades a los hilos pues es una forma de programación eficiente y que da muchas posibilidades al programador.
Además tener varios hilos de ejecución hace que el sistema vaya más rápido que si se ejecutan varios procesos a la ves puesto que se simplifica la gestión por parte del sistema operativo y se evitan los cambios de contexto (un cambio de contexto entre procesos o context switch equivale a una penalización de tiempo cosa que no pasa con los hilos de ejecución que permanecen en el mismo contexto).
Sistemas operativos como Windows 7, 10, OSX y Linux dicen tener hilos «baratos», y procesos «costosos».
Ventajas de los hilos contra procesos
Un proceso se puede denominar proceso monohilo. Los procesos multihilos tienen ventajas que tienen que ver con el rendimiento.
– Es más rápido crear un nuevo hilo que un nuevo proceso (podría llegar a ser 10 veces más rápido).
– Es mucho más rápido eliminar un nuevo hilo que un nuevo proceso.
– Los hilos se pueden comunicar entre sí sin tener que invocar al kernel del sistema operativo.
– Implementa hilos si quieres tener una aplicación que haga varias cosas a la vez de forma interrelacionada.
Ejemplo de una aplicación Contador en Java con Hilos
public Cronometro()
{
_segundos=0;
_corriendo = false;
}
public void iniciar(){
_corriendo = true;
hilo = new Thread( this );
hilo.start();
}
public void parar(){ _corriendo = false;}
public void run() {
String min="", seg="";
try
{
//Mientras _corriendo sea true el tiempo aumenta....
while( _corriendo )
{
Thread.sleep( 100 );
//Incrementamos 100 milésimas de segundo
milesimas += 100;
//Cuando llega a 1000 osea 1 segundo
//ponemos milésimas a 0 y aumentamos los segundos
if( milesimas == 1000 )
{
milesimas = 0;
segundos += 1;
//Si los segundos llegan a 60 entonces aumenta 1 los minutos
//y los segundos vuelven a 0
if( segundos == 60 )
{
segundos = 0;
minutos++;
}
}
//Colocamos el tiempo en formato bonito:
//00:00
if( minutos < 10 ) min = "0" + minutos;
else min = String.valueOf(minutos);
if( segundos < 10 ) seg = "0" + segundos;
else seg = String.valueOf(segundos);
//almacenamos la variable _tiempo y _segundos
_tiempo = min + ":" + seg ;
_segundos = minutos*60+segundos;
}
}catch(Exception e){}
//Cuando se reinicie el Cronómetro colocamos el tiempo a 00:00:000
_tiempo = "00:00" ;
}
public int getTiempo(){ return _segundos; }
public String getTiempoString(){ return _tiempo;}
public boolean estaCorriendo(){ return _corriendo;}
public void reiniciar(){
_segundos=0;
iniciar();
}
public void retraso(int milisegundos){
try {
Thread.sleep(milisegundos);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
/**
* main
*/
public static void main(String[] args) {
Cronometro c = new Cronometro();
c.iniciar();
c.retraso(5500);
System.out.println(_tiempo);
c.parar();
c.retraso(5500);
c.iniciar();
c.retraso(5500);
System.out.println(_tiempo);
}
private static int _segundos;
private static int minutos = 0 ;
private static int segundos = 0;
private static int milesimas = 0;
private static boolean _corriendo;
private static String _tiempo;
Thread hilo;
}