Вы находитесь на странице: 1из 10

INSTITUTO TECNOLGICO DE OAXACA

Tpicos avanzados de programacin


Componentes, paquetes, libreras e hilos
Jos Alberto Castro Lpez 22/04/2013

COMPONENTE Es una clase abstracta que representa todo lo que tiene una posicin, un tamao, puede ser pintado en pantalla y puede recibir eventos. Un componente de software es un elemento de un sistema que ofrece un servicio predefinido, y es capaz de comunicarse con otros componentes. Una definicin ms simple puede ser: Un componente es un objeto escrito de acuerdo a unas especificaciones. No importa que especificacin sea esta, siempre y cuando el objeto se adhiera a la especificacin. Solo cumpliendo correctamente con esa especificacin es que el objeto se convierte en componente y adquiere caractersticas como reusabilidad. Cuando se necesita el acceso a un componente o cuando este debe ser compartido entre distintas redes, se recurre a procesos como la serializacin para entregar el componente a su destino. La capacidad de ser reutilizado (reusability), es una caracterstica importante de los componentes de software de alta calidad. Un componente debe ser diseado e implementado de tal forma que pueda ser reutilizado en muchos programas diferentes. Requiere gran esfuerzo y atencin escribir un componente que es realmente reutilizable. Para esto, el componente debe estar: Completamente documentado. Probado intensivamente: o Debe ser robusto, comprobando la validez de las entradas. o Debe ser capaz de pasar mensajes de error apropiados. Diseado pensando en que ser usado de maneras imprevistas. PAQUETE Un paquete en Java es lo que su nombre lo indica, un paquete o conjunto de clases, lgicamente, que tienen cosas en comn. Lgicamente un programador puede agruparlas con o sin criterio, pero lo ideal es que se dediquen a funciones especficas. Tambin los paquetes definen una jerarqua de directorios, que permiten igualmente agrupas las clases, cosa de desplegar los archivos mas ordenadamente. LIBRERA En ciencias de la computacin, una librera (del ingls library) es un conjunto de subprogramas utilizados para desarrollar software. Las libreras contienen cdigo y datos, que proporcionan servicios a programas independientes, es decir, pasan a formar parte de estos. Esto permite que el cdigo y los datos se compartan y puedan modificarse de forma modular. Algunos programas ejecutables pueden ser a la vez programas independientes y libreras, pero la mayora de estas no son ejecutables. Ejecutables y libreras hacen referencias (llamadas enlaces) entre s a travs de un proceso conocido como enlace, que por lo general es realizado por un software denominado enlazador. La mayora de los sistemas operativos modernos proporcionan libreras que implementan los servicios del sistema. De esta manera, estos servicios se han convertido en una "materia prima" que cualquier aplicacin moderna espera que el sistema operativo ofrezca. Como tal, la mayor parte del cdigo utilizado por las aplicaciones modernas se ofrece en estas libreras. COMPONENTES VISUALES Y NO VISUALES Se pueden establecer muchas clasificaciones para los componentes. Una de ellas es la de visuales o controles, frente a no visuales.

Un componente es visual cuando tiene una representacin grfica en tiempo de diseo y ejecucin (botones, barras de scroll, cuadros de edicin, etc.), y se dice no visual en caso contrario (temporizadores, cuadros de dilogo -no visibles en la fase de dieo-, etc). Por lo dems no existen ms diferencias entre ellos, excepto, claro est, las derivadas de la visualizacin del componente. Los componentes no visuales se pueden colocar en los formularios de la misma manera que los controles, aunque en este caso su posicin es irrelevante. CONCEPTOS BSICOS SOBRE HILOS Un proceso es un programa ejecutndose dentro de su propio espacio de direcciones. Java es un sistema multiproceso, esto significa que soporta varios procesos corriendo a la vez dentro de sus propios espacios de direcciones. Estamos ms familiarizados con el trmino multitarea, el cual describe un escenario muy similar al multiproceso. Por ejemplo, consideremos la cantidad de aplicaciones que corren a la vez dentro de un mismo entorno grfico. Mientras escribo esto, est corriendo Microsoft Word adems de Internet Explorer, Windows Explorer, CD Player y el Volumen Control. Estas aplicaciones son todos procesos ejecutados dentro de Windows 95. De esta forma, se puede pensar que los procesos son anlogos a las aplicaciones o a programas aislados, pero cada proceso tiene asignado espacio propio de ejecucin dentro del sistema. Un hilo es una secuencia de cdigo en ejecucin dentro del contexto de un proceso. Los hilos no pueden ejecutarse ellos solos; requieren la supervisin de un proceso padre para correr. Dentro de cada proceso hay varios hilos ejecutndose. Por ejemplo, Word puede tener un hilo En background chequeando automticamente la gramtica de lo que estoy escribiendo, mientras otro hilo puede estar salvando automticamente los cambios del documento en el que estoy trabajando. Como Word, cada aplicacin (proceso) puede correr varios hilos los cuales estn realizando diferentes tareas. Esto significa que los hilos estn 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 ejecucin. PROGRAMAS DE FLUJO UNICO Un programa de flujo nico, tarea nica o mono -hilo (single-thread) utiliza un nico flujo de control (thread) para controlar su ejecucin. Muchos programas no necesitan la potencia o utilidad de mltiples tareas. Sin necesidad para especificar explcitamente que se quiere un nico flujo de control, muchos de los applets y aplicaciones son de flujo nico. Por ejemplo, en la aplicacin estndar de saludo para aprender cualquier lenguaje de programacin: public class HolaMundo { public static void main (string args[]) { System.out.println( " Hola Mundo " ); } }

Aqu, Cuando se llama al main(), la aplicacin imprime el mensaje y termina. Esto ocurre dentro de una nica tarea (thread). PROGRAMAS DE FLUJO MLTIPLE En la aplicacin de Saludo, no se ve la tarea que est ejecutando el programa. Sin embargo, java posibilita la creacin de tareas explcitamente. La utilizacin de las tareas (threads) en java permite una enorme flexibilidad a los programadores a la hora de plantearse el desarrollo de aplicaciones. La simplicidad para crear, configurar y ejecutar tareas permite que se puedan implementar muy poderosas y portables aplicaciones/applets que no se pueden crear con lenguajes de tercera generacin. En un lenguaje orientado a Internet como es Java, esta herramienta es vital. Si el lector a utilizado un navegador con soporte en Java, ya habr visto el uso de mltiples tareas en Java. Habr observado que dos applets se pueden ejecutar al mismo tiempo, o bien que puede desplazar la pgina del navegador mientras el applet contina ejecutndose. Esto no significa que el applet utilice mltiples tareas, sino que el navegador es multitareas, multihilo, multihilvanado o multithreaded. Los navegadores utilizan diferentes tareas ejecutndose en paralelo para realizar varias tareas, "aparentemente" de forma concurrente. Por ejemplo, en muchas pginas Web se puede desplazar la pgina e ir leyendo el texto antes de que todas la imgenes estn presentes en la pantalla. En este caso, el navegador est descargando las imgenes en una tarea y soportando el desplazamiento de la pgina en otra tarea diferente. Las aplicaciones (y applets) multitarea utiliza muchos contextos de ejecucin para cumplir su trabajo. Se aprovecha del hecho de que muchas tareas contienen subtareas distintas e independientes. Se puede utilizar un hilo de ejecucin para cada subtarea. 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. A continuacin, se va a modificar el programa de saludo creando tres tareas individuales, que imprimen cada una de ellas su propio mensaje de saludo, MultiHola.java: import java.awt.*; import java.awt.event.*; import java.io.*; class TestTh extends Thread { private String nombre; private int retardo; // Constructor para almacenar nuestro nombre y el retraso public TestTh( String s,int d) {

nombre = s; retardo = d; } //El mtodo run() es similar al main(), pero para threads. Cuando // run() termina el thread muere public void run( ) { // Retrasamos la ejecucin el tiempo especificado try { sleep( retardo ); } catch( InterruptedException e ) { ; } // Ahora imprimimos el nombre System.out.println(" Hola Mundo! " +nombre+ " " +retardo ); } } public class MultiHola { public static void main (String args[ ] ) { TestTh t1,t2,t3; //Creamos los threads t1 = new TestTh(" Thread 1", (int)(Math.random()*2000) ); t2 = new TestTh("Thread 2",(int)(Math.random()*2000) ); t3 = new TestTh("Thread 3",(int)(Math.random()*2000)); //Arrancamos las threads t1.start(); t2.start(); t3.start(); } } CREACION Y CONTROL DE HILOS Creacin de un Thread Hay dos modos de conseguir threads en Java. Una es implementando la interface Runnable, la otra es extender la clase Thread. La implementacin 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 disear 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 tendrn que seguir las mismas reglas de funcionamiento. Hay una cuantas diferencias entre interface y clase. Primero, una interface solamente puede contener mtodos abstractos y/o variables estticas y finales (constantes). Las clases, por otro

lado, pueden implementar mtodos y contener variables que no sean constantes. Segundo, una interface no puede implementar cualquier mtodo. Una clase que implemente una interface debe implementar todos los mtodos definidos en esa interface. Una interface tiene la posibilidad de poder extenderse de otras interfaces y, al contrario que las clases, puede extenderse de mltiples interfaces. Adems, 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 mtodo 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 mtodo Thread.run() por su propia implementacin. El mtodo run() es donde se realizar todo el trabajo de la clase. Extendiendo la clase Thread, se pueden heredar los mtodos y variables de la clase padre. En este caso, solamente se puede extender o derivar una vez de la clase padre. Esta limitacin de Java puede ser superada a travs de la implementacin de Runnable: public class MiThread implements Runnable { Thread t; public void run() { // Ejecucin 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. Adems, el mtodo abstracto run() est definido en la interface Runnable tiene que ser implementado. La nica diferencia entre los dos mtodos es que este ltimo es mucho ms flexible. En el ejemplo anterior, todava tenemos oportunidad de extender la clase MiThread, si fuese necesario. La mayora de las clases creadas que necesiten ejecutarse como un thread , implementarn la interface Runnable, ya que probablemente extendern 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 mtodos abstractos, con lo cual es una clase para dar idea sobre el diseo de la clase Thread. De hecho, si vemos los fuentes de Java, podremos comprobar que solamente contiene un mtodo 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 slo proporciona un diseo para las clases que vayan a ser implementadas. En el caso de Runnable, fuerza a la definicin del mtodo run(), por lo tanto, la mayor parte del trabajo se hace en la clase Thread. Un vistazo un poco ms profundo a la definicin 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() ; } } ... } De este trocito de cdigo se desprende que la clase Thread tambin implemente la interface Runnable. tarea.run() se asegura de que la clase con que trabaja (la clase que va a ejecutarse como un thread) no sea nula y ejecuta el mtodo run() de esa clase. Cuando esto suceda, el mtodo run() de la clase har que corra como un thread. Arranque de un Thread Las aplicaciones ejecutan main() tras arrancar. Esta es la razn de que main() sea el lugar natural para crear y arrancar otros threads. La lnea de cdigo: t1 = new TestTh( "Thread 1",(int)(Math.random()*2000) ); crea un nuevo thread. Los dos argumentos pasados representan el nombre del thread y el tiempo que queremos que espere antes de imprimir el mensaje. Al tener control directo sobre los threads, tenemos que arrancarlos explcitamente. En nuestro ejemplo con: t1.start(); start(), en realidad es un mtodo oculto en el thread que llama al mtodo run(). Manipulacin de un Thread Si todo fue bien en la creacin del thread, t1 debera contener un thread vlido, que controlaremos en el mtodo run(). Una vez dentro de run(), podemos comenzar las sentencias de ejecucin como en otros programas. run() sirve como rutina main() para los threads; cuando run() termina, tambin lo hace el thread. Todo lo que queramos que haga el thread ha de estar dentro de run(), por eso cuando decimos que un mtodo es Runnable, nos obliga a escribir un mtodo run().

En este ejemplo, intentamos inmediatamente esperar durante una cantidad de tiempo aleatoria (pasada a travs del constructor): sleep( retardo ); El mtodo sleep() simplemente le dice al thread que duerma durante los milisegundos especificados. Se debera utilizar sleep() cuando se pretenda retrasar la ejecucin del thread. sleep() no consume recursos del sistema mientras el thread duerme. De esta forma otros threads pueden seguir funcionando. Una vez hecho el retardo, se imprime el mensaje "Hola Mundo!" con el nombre del thread y el retardo. Suspensin de un Thread Puede resultar til suspender la ejecucin de un thread sin marcar un lmite de tiempo. Si, por ejemplo, est construyendo un applet con un thread de animacin, querr permitir al usuario la opcin de detener la animacin hasta que quiera continuar. No se trata de terminar la animacin, sino desactivarla. Para este tipo de control de thread se puede utilizar el mtodo suspend(). t1.suspend(); Este mtodo no detiene la ejecucin permanentemente. El thread es suspendido indefinidamente y para volver a activarlo de nuevo necesitamos realizar una invocacin al mtodo resume(): t1.resume(); Parada de un Thread El ltimo elemento de control que se necesita sobre threads es el mtodo stop(). Se utiliza para terminar la ejecucin de un thread: t1.stop(); Esta llamada no destruye el thread, sino que detiene su ejecucin. La ejecucin no se puede reanudar ya con t1.start(). Cuando se desasignen las variables que se usan en el thread, el objeto thread (creado con new) quedar marcado para eliminarlo y el garbage collector se encargar de liberar la memoria que utilizaba. En nuestro ejemplo, no necesitamos detener explcitamente el thread. Simplemente se le deja terminar. Los programas ms complejos necesitarn un control sobre cada uno de los threads que lancen, el mtodo stop() puede utilizarse en esas situaciones. Si se necesita, se puede comprobar si un thread est vivo o no; considerando vivo un thread que ha comenzado y no ha sido detenido. t1.isAlive(); Este mtodo devolver true en caso de que el thread t1 est vivo, es decir, ya se haya llamado a su mtodo run() y no haya sido parado con un stop() ni haya terminado el mtodo run() en su ejecucin.

SINCRONIZACIN DE HILOS Cuando dos o ms hilos necesitan acceder de manera simultnea a un recurso de datos compartido necesitan asegurarse de que slo uno de ellos accede al mismo cada vez. Java proporciona un soporte nico, el monitor, es un objeto que se utiliza como cerrojo exclusivo. Solo uno de los hilos puede ser el propietario de un monitor en un instante dado. Los restantes hilos que estuviesen intentando acceder al monitor bloqueado quedan en suspenso hasta que el hilo propietario salga del monitor. Todos los objetos de Java disponen de un monitor propio implcitamente asociado a ellos. La manera de acceder a un objeto monitor es llamando a un mtodo marcado con la palabra clave synchronized. Durante todo el tiempo en que un hilo permanezca en un mtodo sincronizado, los dems hilos que intenten llamar a un mtodo sincronizado sobre la misma instancia tendrn que esperar. Para salir del monitor y permitir el control del objeto al siguiente hilo en espera, el propietario del monitor slo tiene que volver del mtodo La sentencia synchronized Si se utiliza una clase que no fue diseada para accesos multihilo y, por ello, dispone de mtodos no sincronizados que manipulan el estado interno, puede envolver la llamada al mtodo en un bloque sincronizado. El formato general de la sentencia sincronizada es el siguiente: synchronized(objeto) sentencia; En el ejemplo, objeto es cualquier referencia al objeto, y sentencia suele ser un bloque que incluye una llamada al mtodo de objeto, que solo tendr lugar una vez que el hilo haya entrado con xito en el monitor de objeto. Ahora veremos las formas de sincronizacin con un ejemplo: class Callme { void call (String msg) { * tambin poda haber puesto synchronized antes de void * System.out.print("[" + msg); try Thread.sleep(1000); catch (Exception e); System.out.println("]"); } } class caller implements Runnable { String msg; Callme target; public caller(Callme t, String s) { target = t; msg = s; new Thread(this).start(); } public void run() { synchronized(target) { target.call(msg); } } } class Synch { public static void main(String args[]) { Callme target = new Callme();

new caller(target, "Hola"); new caller(target, "Mundo"); new caller(target, "Sincronizado"); } } Este programa imprime por pantalla el literal "Hola Mundo Sincronizado", cada palabra en una lnea y entre comillas, se crea una instancia de Callme y tres instancias de caller que cada una de ellas referencia al mismo Callme con lo que necesitamos de una sincronizacin para el acceso a Callme, pues sino se mezclaran las tres llamada al haber una sentencia sleep que retrasa la ejecucin de Callme dando lugar a que antes de que acabe un proceso deje libre el acceso a dicho objeto.

Вам также может понравиться