martes, 9 de noviembre de 2010

Hilos

1. HILO

Un hilo es una secuencia de código en ejecución dentro del contexto de un proceso. Los hilos no pueden ejecutarse ellos solos; requieren la supervisión de un proceso padre para correr.

Dentro de cada proceso hay varios hilos ejecutándose. Por ejemplo, Word puede tener un hilo en background chequeando automáticamente la gramática de lo que estoy escribiendo, mientras otro hilo puede estar salvando automáticamente los cambios del documento en el que estoy trabajando. Como Word, cada aplicación (proceso) puede correr varios hilos los cuales están realizando diferentes tareas. Esto significa que los hilos están siempre asociados con un proceso en particular.

Los hilos a menudo son conocidos o llamados procesos ligeros. Un hilo, en efecto, es muy similar a un proceso pero con la diferencia de que un hilo siempre corre dentro del contexto de otro programa. Por el contrario, los procesos mantienen su propio espacio de direcciones y entorno de operaciones. Los hilos dependen de un programa padre en lo que se refiere a recursos de ejecución. La siguiente figura muestra le relación entre hilos y procesos.

2. Estados de un Hilo

El comportamiento de un hilo depende del estado en que se encuentre, este estado define su
modo de operación actual, por ejemplo, si esta corriendo o no. A continuación proporcionamos
la relación de estados en los que puede estar un hilo Java.
• New
• Runnable
• Not running
• Dead

New
Un hilo esta en el estado new la primera vez que se crea y hasta que el método start es
llamado. Los hilos en estado new ya han sido inicializados y están listos para empezar a trabajar,
pero aún no han sido notificados para que empiecen a realizar su trabajo.

Runnable
Cuando se llama al método start de un hilo nuevo, el método run es invocado y el hilo entra
en el estado runnable. Este estado podría llamarse “running” porque la ejecución del método
run significa que el hilo esta corriendo. Sin embargo, debemos tener en cuenta la prioridad de
los hilos. Aunque cada hilo está corriendo desde el punto de vista del usuario, en realidad todos
los hilos, excepto el que en estos momentos esta utilizando la CPU, están en el estado runnable
(ejecutables, listos para correr) en cualquier momento dado. Uno puede pensar conceptualmente
en el estado runnable como si fuera el estado “running”, sólo tenemos que recordar que todos
los hilos tienen que compartir los recursos del sistema.  

Not running
El estado not running se aplica a todos los hilos que están parados por alguna razón. Cuando un
hilo está en este estado, está listo para ser usado y es capaz de volver al estado runnable en un
momento dado. Los hilos pueden pasar al estado not running a través de varias vías.
A continuación se citan diferentes eventos que pueden hacer que un hilo esté parado de modo
temporal.

• El método suspend ha sido llamado
• El método sleep ha sido llamado
• El método wait ha sido llamado
• El hilo esta bloqueado por I/O

Para cada una de estas acciones que implica que el hilo pase al estado not running hay una
forma para hacer que el hilo vuelva a correr. A continuación presentamos la lista de eventos
correspondientes que pueden hacer que el hilo pase al estado runnable.

• Si un hilo está suspendido, la invocación del método resume
• Si un hilo está durmiendo, pasarán el número de milisegundos que se ha
especificado que debe dormir
• Si un hilo está esperando, la llamada a notify o notifyAll por parte del
objeto por el que espera
• Si un hilo está bloqueado por I/O, la finalización de la operación I/O en cuestión



Dead
Un hilo entra en estado dead cuando ya no es un objeto necesario. Los hilos en estado dead no
pueden ser resucitados y ejecutados de nuevo. Un hilo puede entrar en estado dead a través de
dos vías:

• El método run termina su ejecución.
• El método stop es llamado.

La primera opción es el modo natural de que un hilo muera. Uno puede pensar en la muerte
de un hilo cuando su método run termina la ejecución como una muerte por causas naturales.
En contraste a esto, está la muerte de un hilo “por causa” de su método stop. Una llamada al
método stop mata al hilo de modo asíncrono.


 
Aunque la segunda opción suene un poco brusca, a menudo es muy útil. Por ejemplo, es
bastante común que los applets maten sus hilos utilizando el método stop cuando el propio
método stop del applet ha sido invocado. La razón de esto es que el método stop del applet
es llamado normalmente como respuesta al hecho de que el usuario ha abandonado la página
web que contenía el applet y no es adecuado dejar hilos de un applet corriendo cuando el applet
no está activo, así que es deseable matar los hilos.



Hay dos modos de conseguir threads en Java. Una es implementando la interface Runnable, la otra es extender la clase Thread.

La implementación de la interface Runnable es la forma habitual de crear threads. Las interfaces proporcionan al programador una forma de agrupar el trabajo de infraestructura de una clase. Se utilizan para diseñar los requerimientos comunes al conjunto de clases a implementar. La interface define el trabajo y la clase, o clases, que implementan la interface realizan ese trabajo. Los diferentes grupos de clases que implementen la interface tendrán que seguir las mismas reglas de funcionamiento.

Hay una cuantas diferencias entre interface y clase. Primero, una interface solamente puede contener métodos abstractos y/o variables estáticas y finales (constantes). Las clases, por otro lado, pueden implementar métodos y contener variables que no sean constantes. Segundo, una interface no puede implementar cualquier método. Una clase que implemente una interface debe implementar todos los métodos definidos en esa interface. Una interface tiene la posibilidad de poder extenderse de otras interfaces y, al contrario que las clases, puede extenderse de múltiples interfaces. Además, una interface no puede ser instanciada con el operador new; por ejemplo, la siguiente sentencia no está permitida:

Runnable a = new Runnable();   // No se permite
El primer método de crear un thread es simplemente extender la clase Thread:
class MiThread extends Thread {
    public void run() {
        . . .
        }

El ejemplo anterior crea una nueva clase MiThread que extiende la clase Thread y sobrecarga el método Thread.run() por su propia implementación. El método run() es donde se realizará todo el trabajo de la clase. Extendiendo la clase Thread, se pueden heredar los métodos y variables de la clase padre. En este caso, solamente se puede extender o derivar una vez de la clase padre. Esta limitación de Java puede ser superada a través de la implementación de Runnable:

public class MiThread implements Runnable {
    Thread t;
    public void run() {
        // Ejecución del thread una vez creado
        }
    }

En este caso necesitamos crear una instancia de Thread antes de que el sistema pueda ejecutar el proceso como un thread. Además, el método abstracto run() está definido en la interface Runnable tiene que ser implementado. La única diferencia entre los dos métodos es que este último es mucho más flexible. En el ejemplo anterior, todavía tenemos oportunidad de extender la clase MiThread, si fuese necesario. La mayoría de las clases creadas que necesiten ejecutarse como un thread , implementarán la interface Runnable, ya que probablemente extenderán alguna de su funcionalidad a otras clases.

No pensar que la interface Runnable está haciendo alguna cosa cuando la tarea se está ejecutando. Solamente contiene métodos abstractos, con lo cual es una clase para dar idea sobre el diseño de la clase Thread. De hecho, si vemos los fuentes de Java, podremos comprobar que solamente contiene un método abstracto:

package java.lang;
public interface Runnable {
    public abstract void run() ;
}

Y esto es todo lo que hay sobre la interface Runnable. Como se ve, una interface sólo proporciona un diseño para las clases que vayan a ser implementadas. En el caso de Runnable, fuerza a la definición del método run(), por lo tanto, la mayor parte del trabajo se hace en la clase Thread. Un vistazo un poco más profundo a la definición de la clase Thread nos da idea de lo que realmente está pasando:
public class Thread implements Runnable 




{
   ...
    public void run() {
        if( tarea != null )
            tarea.run() ;
            }
        }
    ...
    }

4. MÉTODOS 

public static Thread currentThread ()
Retorna una referencia al hilo que se está ejecutando actual­mente.


public static void dumpStack ()
Imprime una traza del hilo actual. Usado sólo con propósitos de depuración.


public String getName ()
Retorna el nombre del hilo.


 int getPriority ()
Retorna la prioridad del hilo. 


public final boolean isAlive ()
Chequea si el hilo está vivo. Un hilo está vivo si ha sido lanzado con start y no ha muerto todavía. 


public final void isDaemon ()
Devuelve verdadero si el hilo es daemon.


public foral void join () throws InterruptedException
Espera a que este hilo muera.


 public final void join (long millis) throws InterruptedException
Espera como mucho millis milisegundos para que este hilo muera.


 public final void join (long millis, int nonos) throws InterruptedException
Permite afinar con los nanosegundos nanos el tiempo a es­perar.




 public void resume ()
Se usa para recomenzar un hilo que esta suspendido.
NOTA: resume=reanudar. 


public void run ()
Si este hilo fue construido usando un objeto que implemen­taba Runnable, entonces el método run de ese objeto es lla­mado. En cualquier otro caso este método no hace nada y retorna. 


public final void setDaemon (boolean on)
Marca este hilo como daemon si el parámetro on es verda­dero o como hilo de usuario si es falso. El método debe ser llamado antes de que el hilo sea lanzado.


 public foral void setName (String name)
Cambia el nombre del hilo por name.


 public final void setPriority (int newPriority)
Asigna la prioridad newPriority a este hilo.
NOTA: acepta valores de 1 a 10.

 public static void sleep (long millis) throws InterruptedException
Hace que el hilo que se está ejecutando actualmente cese su ejecución por los milisegundos especificados en millis. Pasa al estado dormido. El hilo no pierde la propiedad de ningún cerrojo que tuviera adquirido con synchronized. 


public static void sleep (long millis, int manos) throws InterruptedException
Permite afinar con los nanosegundos nanos el tiempo a estar dormido.


 public void start ()
Hace que el hilo comience su ejecución. La MVJ llamará al método run de este hilo. public void stop ()
Hace que el hilo termine su ejecución. 




public void suspend ()
Hace que el hilo interrumpa temporalmente su ejecución.


public String toString ()
Devuelve una representación en forma de cadena de este hi­lo, incluyendo su nombre, su prioridad y su grupo.


 public static void yield ()
Hace que el hilo que se está ejecutando actualmente pase al estado listo, permitiendo a otro hilo ganar el procesador.
NOTA: yield=ceder el paso.

5. La interfaz Runnable


 
A veces no es conveniente extender la clase Thread porque se pierde la posibilidad de extender otro objeto. Es una de las razones por que existe la interfaz Runnable que declara nada más que el método public void run() y que se puede usar fácilmente para crear hilos trabajadores.




class RunPingPONG implements Runnable {
  private String word;
  private int delay;
 
  RunPingPONG(String whatToSay, int delayTime) {
    word =whatToSay;
    delay=delayTime;
  }
 
  public void run() {
    try {
      for(;;) {
        System.out.print(word+" ");
        Thread.sleep(delay);
      }
    }
    catch(InterruptedException e) {
      return;
    }
  }
 
  public static void main(String[] args) {
    Runnable ping = new RunPingPONG("ping", 40);
    Runnable PONG = new RunPingPONG("PONG", 50);
    new Thread(ping).start();
    new Thread(PONG).start();
  }
}
Existen cuatro constructores para crear hilos usando la interfaz Runnable.

  • public Thread(Runnable target)
    así lo usamos en el ejemplo arriba, se pasa solamente la implementación de la interfaz Runnable
  • public Thread(Runnable target, String name)
    se pasa adicionalmente un nombre para el hilo
  • public Thread(ThreadGroup group, Runnable target)
    construye un hilo dentro de un grupo de hilos
  • public Thread(ThreadGroup group, Runnable target, String name)
    construye un hilo con nombre dentro de un grupo de hilos
La interfaz Runnable exige solamente el método run(), sin embargo, normalmente se implementan más métodos para crear un servicio completo que este hilo debe cumplir.
Aunque no hemos guardado las referencias de los hilos en unas variables, los hilos no caen en las manos del recolector de memoria: siempre se mantiene una referencia al hilo en su grupo al cual pertenece. 



El método run() es público y en muchos casos, implementando algún tipo de servicio, no se quiere dar permiso a otros ejecutar directamente el método run(). Para evitar eso se puede recurrir a la siguiente construcción: 

class Service {
  private Queue requests = new Queue();
  public Service() {
    Runnable service = new Runnable() {
      public void run() {
        for(;;) realService((Job)requests.take());
      }
    };
    new Thread(service).start();
  }
  public void AddJob(Job job) {
    requests.add(job);
  }
  private void realService(Job job) {
    // do the real work
  }
}
 
Crear el servicio con Service() lanza un nuevo hilo que actua sobre una cola para realizar su trabajo con cada tarea que encuentra ahí. El trabajo por hacer se encuentra en el método privado realService(). Una nueva tarea se puede añadir a la cola con AddJob(...)


Nota: la construcción arriba usa el concepto de clases anónimas de Java, es decir, sabiendo que no se va a usar la clase en otro sitio que no sea que en su punto de construcción, se declara directamente donde se usa. 

BIBLIOGRAFIA

miércoles, 29 de septiembre de 2010

Cluster

¿Qué es exactamente un sistema Cluster?

Este tipo de sistemas se basa en la unión de varios servidores que trabajan como si de uno sólo se tratase. Los sistemas cluster han evolucionado mucho desde su primera aparición, ahora se pueden crear distintos tipos de clusters, en función de lo que se necesite:

- Unión de Hardware
- Clusters de Software
- Alto rendimiento de bases de datos

Estas son solo algunas de las opciones que tenemos disponibles. En resumen, cluster es un grupo de múltiples ordenadores unidos mediante una red de alta velocidad, de tal forma que el conjunto es visto como un único ordenador, más potente que los comunes de escritorio. De un sistema de este tipo se espera que presente combinaciones de los siguientes servicios:

- Alto rendimiento
- Alta disponibilidad
- Equilibrio de carga
- Escalabilidad

Para que un sistema cluster funcione no es necesario que todas las máquinas dispongan del mismo Hardware y sistema operativo (cluster heterogéneo). Este tipo de sistemas debe de disponer de un interfaz de manejo de clusters, la cual se encargue de interactuar con el usuario y los procesos, repartiendo la carga entre las diferentes máquinas del grupo. 
 
¿Qué componentes necesita un cluster para funcionar?

Por norma general un cluster hace uso de diferentes componentes para funcionar, entre estos están:

- Nodos (Ordenadores o servidores)
- Sistema operativo
- Conexión de Red (ampliado más abajo)
- Middleware (capa entre el usuario y el sistema operativo)
- Protocolos de comunicación y servicio
- Aplicaciones

Nodos:
Los nodos pueden ser ordenadores de escritorio o servidores, de hecho se puede establecer un cluster con cualquier tipo de máquina.

Sistema operativo:
Este debe de tener un entorno multiusuario, cuanto más fácil sea el manejo del sistema menores problemas tendremos. Comúnmente Solingest instala sus cluster con sistemas Microsoft Cluster Services (MSCS), pero es totalmente factible la instalación de un Cluster con un sistema Linux o Unix como podrían ser Rocks (Linux) o Solaris (Unix).

Han surgido ocasiones en las que se ha requerido el montaje de un sistema cluster en Mac OS X, sobretodo en Granjas de render (para procesado 3D).

Conexiones de Red:
Las conexiones utilizadas en este tipo de sistema pueden ser muy variadas, se pueden utilizar desde simples conexiones Ethernet con placas de red comunes o sistemas de alta velocidad como Fast Ethernet, Gigabit Ethernet, Myrinet, Infiniband, SCI, etc.

Middleware:
El middleware es el software que actúa entre el sistema operativo y las aplicaciones, y que brinda al usuario la experiencia de estar utilizando una única super máquina. Este software provee una única interfaz de acceso al sistema, denominada SSI (Single System Image). Optimiza el sistema y provee herramientas de mantenimiento para procesos pesados como podrían ser migraciones, balanceo de carga, tolerancia de fallos, etc.

Este sistema también se encarga de la escalabilidad del cluster, detectando nuevas máquinas y añadiéndolas al grupo.

Por lo tanto, si un cliente quisiera disponer de un cluster para su servidor Web, este podría optar entre diferentes opciones. No habría ningún problema en instalar un cluster que tuviese un sistema MySQL y PHP repartido entre diferentes máquinas.

 

lunes, 23 de agosto de 2010

Applet


programacion Applet:

Un applet es una clase de Java que corre dentro de un navegador y que no puede hacer referencias a archivos, también posee su interfaz gráfica.

los applet son programas diseñados para ejecutarse como parte de una pagina Web 

La programación del applet se hace bajo un framework que
implementa gran parte de la Graphical User Interface (GUI)

• Las applet poseen limitaciones por razones de seguridad; por ejemplo
no se está permitido manipular archivos locales.

CARACTERISTICAS:

applets redefinen estos 4 métodos:

 
public class Simple extends Applet {
. . .
public void init() { . . . }
public void start() { . . . }
public void stop() { . . . }
public void destroy() { . . . }
. . .
}
– init

• Para inicializar el applet cada vez que se carga o se recargaç
• Suele usarse para operaciones cortas de inicialización (por
ejemplo, cargar imágenes)

– start

• Para comenzar la ejecución del applet: cuando el applet se carga
o cuando se revisita la página web

– stop

• Para detener la ejecución del applet: cuando se abandona la
página web o se cierra el explorador

– destroy

• Para realizar operaciones de limpieza (liberar recursos) antes de
descargar el applet

Para visualizar objetos, los applets pueden redefinir 2 métodos heredados de AWT:

 
 
AWT (Abstract Window Toolkit) es la parte de Java diseñada para crear interfaces de usuario y para dibujar gráficos e imágenes. Es un conjunto de clases que intentan ofrecer al desarrollador todo lo que necesita para crear una interfaz de usuario para cualquier applet o aplicación Java. La mayoría de los componentes AWT descienden de la clase java.awt.Component como podemos 



  paint


• Es el método básico de visualización. Se usa
para dibujar la representación del applet dentro
de la página web.

– update
• Se usa para redibujarel applet
Para reaccionar ante eventos, los applets pueden redefinirse:

– Métodos específicos de manejo del evento
(ejemplo: mouseDown)

 – El método handleEvent.


Swing: es un extenso conjunto de componentes que van desde los más simples, como etiquetas, hasta los más complejos, como tablas, árboles, y documentos de texto con estilo. Casi todos los componentes Swing descienden de un mismo padre llamado JComponent que desciende de la clase de AWT Container. Es por ello que Swing es más una capa encima de AWT que una sustitución del mismo.

A los componentes Swing se les denomina ligeros mientras que a los componentes AWT se les
denominados pesados.

Otros componentes visuales heredados de AWT:


Botones (java.awt.Button)
Checkbox (java.awt.Checkbox)
Campos de texto de una línea (java.awt.TextField)
Áreas de edición más grandes (java.awt.TextArea)
Etiquetas (java.awt.Label)
Listas (java.awt.List)
Listas desplegables (java.awt.Choice)
Sliders y barras de desplazamiento (java.awt.Scrollbar)
Áreas de dibujo (java.awt.Canvas)
Menús (java.awt.Menu, java.awt.MenuItem,
    java.awt.CheckboxMenuItem)
Contenedores (java.awt.Panel, java.awt.Window and its subclasses)



La clase TextField

 

La clase TextField proporciona un editor de texto diseñado para ser usado dentro de los forms. Esta es la principal diferencia con respecto a la clase TextBox. A pesar de esta diferencia, estas dos clases tienen su parecido. De hecho, se puede interactuar con el texto en la clase TextField usando los mismo métodos que se especificaron anteriormente en la clase TextBox. El constructor de la clase TextField es:


TextField(String label, String text, int maxSize, int constraints)

 El primer parámetro establece la etiqueta que se muestra junto al componente y el segundo el texto utilizado para inicializar el elemento. El parámetro maxSize indica el máximo número de caracteres que pueden ser introducidos. El último parámetro, de forma similar a lo indicado para la clase TextBox, indica las restricciones del texto a introducir. Como ya se indicó, los valores
pueden ser:


ANY – No hay limitaciones en el texto
o EMAILADDR – Sólo se puede introducir una dirección de correo
electrónico
o NUMERIC – Sólo se puede introducir un valor entero
o PASSWORD – El texto es protegido para que no sea visible
o PHONENUMBER – Sólo se puede introducir un número de
teléfono
o URL – Sólo se puede introducir una URL


public class Button
 
public class Button
Componente sí se extiende extiende de Componentes
aplicación implementa Accesible Accesible

Esta clase crea un botón. This creación Clase sin Boton. La aplicación puede causar algún tipo de acción que ocurra cuando se pulsa el botón. La Aplicación PUEDE causar Algún Tipo de Acción de Cuando ocurra Que sí Pulsa El Botón. 
 
public class Etiqueta label 
 Componente sí se extiende extiende de Componentes
aplicación implementa Accesible Accesible
Un objeto Label es un componente para colocar texto en un contenedor. Una etiqueta es sin Objeto Componente párr colocar texto contenedor en la ONU. Una etiqueta muestra una sola línea de texto de sólo lectura. El texto puede ser modificado por la aplicación, pero un usuario no puede editarlo directamente. Una Etiqueta Muestra Una Sola Línea de texto de Sólo lectura. El texto Se Puede Cambiar Por la Aplicación, Usuario Pero sin ninguna Directamente PUEDE editarlo.
Por ejemplo, el código. . . Por Ejemplo, el ... Código

     
setLayout (FlowLayout nuevo (FlowLayout.CENTER, 10, 10)); setLayout (FlowLayout nuevo (FlowLayout.CENTER, 10, 10));
     
add (new Label ("Hola !")); añadir (nuevo sello (" Hola !"));
     
add (new Label ("Otra etiqueta")); add (nuevo sello ("Otra Etiqueta"));