Sei sulla pagina 1di 18

Multiprocesos en Java: Hilos(Threads)

El flujo mltiple de ejecucin de programas permite que se estn realizando diferentes


tareas al mismo tiempo en un programa, es decir, que las tareas se ejecuten de forma
paralela, para ello Java utiliza unos elementos llamados hilos (thread).
Cada hilo realiza una tarea en especfico, al tener varios hilos ejecutndose, se tendrn
varias tareas corriendo en el mismo programa. Lo que permitir que en el mismo
programa se estn realizando diferentes actividades al mismo tiempo.
En Java, as como en cualquier lenguaje de programacin, la principal estructura de
ejecucin de instrucciones es la estructura secuencial, en la que cada comando, cada
lnea, cada instruccin se ejecuta una despus de otra. El cdigo se ejecuta de arriba
hacia abajo y cada lnea es ejecutada segn el orden en que haya sido escrita por el
programador.
El diagrama de flujo siguiente lo ejemplifica:

En ocasiones puede que el usuario necesite llevar a cabo 2 o ms procesos a la vez.


Supongamos que queremos realizar 3 procesos al mismo tiempo, como lo vemos en este
modelo:

Esto es completamente IMPOSIBLE ya que el procesador de una computadora no es


capaz de realizar estas funciones. Sin embargo existen alternativas, como los Hilos o
Threads.
Si vemos el diagrama de arriba, podemos identificar 3 hilos: Proceso 1, Proceso 2 y
Proceso 3. Pero, ya hemos dicho que esto no es posible de la forma como lo hemos
presentado en el diagrama de flujo.
Si intentamos utilizar una estructura secuencial para ejecutar 3 procesos, obtendremos el
siguiente resultado:

Existe una serie de inconvenientes con esto: el proceso 1 slo se ejecutar cuando haya
terminado el proceso 2. El proceso 3 se empezar a ejecutar cuando haya terminado el
proceso 1 y 2.
Con los hilos o threads, podemos obtener una ejecucin lo ms cercana posible al modelo
de los 3 hilos que present arriba. Los threads son estructuras secuenciales que
combinan las lneas de 2 o ms procesos en un solo proceso.
Si lo expresamos con un diagrama de flujo se vera de la siguiente forma:

Los comandos en azul pertenecen al proceso 1, los comandos en rojo son del proceso 2 y
el rojo del proceso 3.
La forma como se ejecutan los procesos es completamente aleatoria. Puede que se inicie
la ejecucin con el proceso 2, luego el 2, luego el 3, luego el 1 y as sucesivamente.
No siguen un orden especfico. Esto permite que los 3 vallan corriendo al mismo tiempo,
dando como resultado algo bastante parecido a aquel modelo que ya hemos dicho que no
es posible obtener con los procesadores de nuestras computadoras.
Mientras que los programas de flujo nico pueden realizar su tarea ejecutando las subtareas secuencialmente, un programa multitarea permite que cada tarea comience y

termine tan pronto como sea posible. Este comportamiento presenta una mejor respuesta
a la entrada en tiempo real.
Los hilos de ejecucin en Java estn implementados en la clase thread, que forma parte
del paquete java.lang.
Cada hilo (thread) tiene un principio, un flujo de ejecucin y un fin definidos, pero no es
una entidad independiente sino que debe ejecutarse en el contexto de un programa
(Joyanes, 2002).

Veamos cmo funcionan los Threads con una aplicacin en Java. Vamos a Netbeans y
creamos un proyecto llamado Threads. Insertamos un JFrame y le colocamos un botn
con el que iniciaremos la ejecucin se los Threads.

Ahora vamos al cdigo y declaramos 3 variables tipo Thread.

Ahora vamos a programar el botn que colocamos en el JFRame.


Dentro del cdigo del botn iniciaremos los threads. Colocamos lo siguiente:

Aqu Netbeans marca 3 errores con la inicializacin de los threads. Esto se debe a que
necesitamos implementar la interfaz Runnable en la Clase de nuestra JFrame.
Lo corregimos dando clic en el cono de la izquierda en nuestra declaracin de la clase
public class ThreadsG extends javax.swing.JFrame { para corregir el error. Nos aparecer
la opcin Implement all abstract methods, quedara de la siguiente manera: public class
ThreadsG extends javax.swing.JFrame implements Runnable{

Para ver como se ejecutan los threads, veremos una carrera de 3 procesos.
Primero declararemos 3 variables, c1, c2 y c3. Sern del tipo entero y las inicializaremos
en 0.
Luego introduciremos los siguientes mtodos:
public void corredor1() {
c1++;
}
public void corredor2() {
c2++;
}
public void corredor3() {
c3++;
}

Estos mtodos lo que harn es que le agregarn una unidad a cada una de las variables,
es decir, c1, c2 y c3. Ahora nos dirigimos al final del programa, donde est el
mtodo public void run().
All colocamos lo siguiente:
Thread ct = Thread.currentThread();
while (ct == hilo1) {
corredor1();
System.out.println("Corredor 1: " + c1);
}
while (ct == hilo2) {
corredor2();
System.out.println("Corredor 2: " + c2);
}
while (ct == hilo3) {

corredor3();
System.out.println("Corredor 3: " + c3);
}

/
Esto funciona de la siguiente manera:
La variable ct adoptar el valor del CurrenThread, es decir, el hilo que se est ejecutando
en determinado instante.
Mientras

ese

hilo

funcincorredor1 que

que
es

se
la

est

ejecutando

encargada

de

sea

aumentar

el hilo1,
la

se

ejecutar

variable c1. La

la

funcin

System.out.println(Corredor 1: + c1); imprime el valor de c1 en la parte inferior de


Netbeans IDE.
Se repite el mismo proceso para los otros 2 hilos. Lo que queremos darnos cuenta es
como Java ejecuta el cdigo. Lo hemos colocado uno debajo del otro, como una
secuencia, pero al ejecutar el programa y presionar el botn nos damos cuenta de que no
es una secuencia.
Cuando ejecutamos el programa obtenemos lo siguiente:

Como podemos observar, el proceso inici ejecutndose con el mtodo 1 (corredor1) pero
al llegar a la lnea 493 se volvi aleatorio, es decir, el proceso 2 y 3 empezaron a
ejecutarse a medida que el proceso 1 tambin se ejecutaba.
Si detenemos el programa y empezamos una nueva ejecucin obtendremos otro tipo de
comportamiento.

/
Ahora el primer proceso en ejecutarse fue el proceso 1, luego el 3 y despus el 2. Es
probable que cada vez que ejecutemos el programa obtendremos resultados diferentes.
Podemos observar que no es necesario esperar que el proceso 1 se termine de ejecutar
para empezar con el 2 y el 3, sino que los 3 se ejecutarn en manera conjunta.

Al final le hice unas modificaciones al cdigo para obtener los resultados en


una interfaz grfica utilizando jFrame, el sistema se detiene cuando cualquiera
de los Corredores llega a 500 para este ejemplo.

El cdigo es el siguiente:
/*
* Jos Luis Rubio Padilla
* Manejo de Hilos en JAVA
*
*/
package threads;

/**
*

* @author jlrubio
*/
public class ThreadsG extends javax.swing.JFrame implements Runnable{
//Estas variables sirven para dar nombre a lo hilos y
//se imprimirn cada vez que los hilos estn en ejecucin.
Thread hilo1;
Thread hilo2;
Thread hilo3;
int c1=0, c2=0, c3=0; //Inicializa las cariables que se utilizaran para
ejemplificar los hilos
String texto1="", texto2="", texto3="";

//Estos metodos incrementan la variable en uno, se ejectaran en hilos


diferentes
public void corredor1() {
c1++;
}

public void corredor2() {


c2++;
}

public void corredor3() {


c3++;
}

/**
* Creates new form ThreadsG
*/
public ThreadsG() {
initComponents();
}

/**

*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

jButton1 = new javax.swing.JButton();


jScrollPane1 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jButton1.setText("Ejecutar hilos");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});

jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jScrollPane1.setViewportView(jTextArea1);

javax.swing.GroupLayout layout = new


javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()

.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEA
DING)
.addComponent(jButton1)
.addComponent(jScrollPane1,
javax.swing.GroupLayout.PREFERRED_SIZE, 312,
javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1)
.addGap(18, 18, 18)
.addComponent(jScrollPane1,
javax.swing.GroupLayout.DEFAULT_SIZE, 422, Short.MAX_VALUE)
.addContainerGap())
);

pack();
}// </editor-fold>

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
hilo1 = new Thread(this);
hilo2 = new Thread(this);
hilo3 = new Thread(this);

hilo1.start();
hilo2.start();

hilo3.start();

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code
(optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default
look and feel.
* For details see
http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info :
javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(ThreadsG.class.getName()).log(java.util.loggi
ng.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(ThreadsG.class.getName()).log(java.util.loggi
ng.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {

java.util.logging.Logger.getLogger(ThreadsG.class.getName()).log(java.util.loggi
ng.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(ThreadsG.class.getName()).log(java.util.loggi
ng.Level.SEVERE, null, ex);
}
//</editor-fold>

/* Create and display the form */


java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ThreadsG().setVisible(true);
}
});
}

// Variables declaration - do not modify


private javax.swing.JButton jButton1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextArea jTextArea1;
// End of variables declaration

@Override
public void run() {
Thread ct = Thread.currentThread();

while (ct == hilo1) {

corredor1();
texto1=texto1 + "Corredor 1: " + c1 + "\n";

this.jTextArea1.setText(texto1); //se colcoca el resultado en el


contro,jTextArea

System.out.println("Corredor 1: " + c1);


if (c1==500) break; //Al llegar a 500 ejecuciones detengo la ejecucin
para observar el resultado
}

while (ct == hilo2) {

corredor2();
texto1=texto1 + "Corredor 2: " + c2 + "\n";
this.jTextArea1.setText(texto1); //se colcoca el resultado en el
contro,jTextArea
System.out.println("Corredor 2: " + c2);
if (c2==500) break; //Al llegar a 500 ejecuciones detengo la ejecucin
para observar el resultado
}

while (ct == hilo3) {

corredor3();
texto1=texto1 + "Corredor 3: " + c3 + "\n";
this.jTextArea1.setText(texto1); //se colcoca el resultado en el
contro,jTextArea
System.out.println("Corredor 3: " + c3);
if (c3==500) break; //Al llegar a 500 ejecuciones detengo la ejecucin
para observar el resultado
}

throw new UnsupportedOperationException("Not supported yet."); //To


change body of generated methods, choose Tools | Templates.

}
}

Conclusiones: Con los hilos de ejecucin podemos terminar mucho ms


rpido nuestra aplicacin, sobre todo cuando son grandes volmenes de datos
o clculos que se tienen que procesar.

Potrebbero piacerti anche