Descarga la aplicación para disfrutar aún más
Vista previa del material en texto
Carátula para entrega de prácticas Facultad de Ingeniería Laboratorio de docencia Laboratorios de computación salas A y B Profesor: Saavedra Hernández Honorato Ing. Asignatura: Programación Orientada a Objetos Grupo: 1 No de Práctica(s): 12 Integrante(s): Ayala Trejo Albanya Yendalli Téllez González Jorge Luis Méndez Costales Luis Enrique Villamar Cortes Juan Antonio Santana Sánchez María Yvette Zecua Salinas Juan Carlos Téllez González Jorge Luis Villamar Cortes Juan Antonio Zecua Salinas Juan Carlos No. de Equipo de cómputo empleado: --- No. de Lista o Brigada: --- Semestre: 2020-2 Fecha de entrega: 06/05/2020 Observaciones: CALIFICACIÓN: __________ Facultad de Ingenierı́a Programación Orientada a Objetos Índice 1. Objetivo 2 2. Introducción 2 3. Hilos (threads) 2 3.1. Hilos en Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3.2. Ciclo de vida de un hilo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3.3. Planificador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 3.4. Prioridad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 4. Clase Thread 5 4.1. Interfaz Runnable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 4.2. ThreadDead . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 4.3. ThreadGroup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 4.4. Métodos o bloques sincronizados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 5. Conclusiones 12 1 Facultad de Ingenierı́a Programación Orientada a Objetos 1. Objetivo Implementar el concepto de multitarea utilizando hilos en un lenguaje de programación orientado a objetos, además de utilizar la clase Thread y la interfaz Runnable. 2. Introducción Para comenzar esta práctica debemos plantear cómo resolver un problema de un problema. Normalmente cuando vamos a ejecutar una solución lo hacemos de forma secuencial, es decir, un paso después del otro. Para realizar estos pasos tenemos un inconveniente, si tuviésemos una aplicación departamental que realice operaciones complejas, donde sus funciones radiquen en descargar el catálogo de precios de los productos nuevos y hacer la contabilidad del dı́a anterior, aplicando descuentos a los productos existentes, hasta ahı́ no existe inconveniente hasta que planteamos la posibilidad de que la descarga de productos nuevos tardase, en cuyo caso los descuentos no se podrı́an aplicar hasta que este proceso termine lo que impedirı́a realizar el descuento, si esto es lo que se desea. Figura 1: Una tienda departamental tiene varios procesos realizandose al mismo tiempo. La necesidad nos llevarı́a a tener varios flujos de ejecución para poder realizar una tarea sin nece- sidad de esperar a las anteriores, esto se puede lograr utilizando hilos, donde cada hilo representarı́a una determinado tarea en un proceso. 3. Hilos (threads) Un hilo es un flujo único de ejecución dentro de un proceso; un programa en ejecución dentro de su propio espacio de direcciones. Un Hilo, es por esto, una secuencia de código en ejecución dentro del contexto de un proceso, esto se debe a que los hilos no pueden ejecutarse solos, hay que supervisarlos en un proceso. 2 Facultad de Ingenierı́a Programación Orientada a Objetos Figura 2: Un hilo requiere de supervisión para su ejecución. 3.1. Hilos en Java La Máquina virtual de Java es capaz de manejar multihilos, lo que implica crear varios flujos de ejecución de manera simultánea, administrando los detalles como asignar tiempos de ejecución o priorizar los hilos, de forma similar a lo que efectúa un sistema operativo para múltiples procesos. Java proporciona soporte para hilos a través de una interfaz y un conjunto de clases, la interfaz de java y las clases proporcionan funcionalidades sobre hilos. Estas clases son la siguientes: Thread Runnable (Interfaz) ThreadGroup ThreadDeath Object Las clases y la interfaz son parte del paquete básico de java ( java.lang). 3.2. Ciclo de vida de un hilo Un hilo puede pasar por diferentes etapas de acuerdo a su estado; desde que es creado hasta que cumple su propósito y ya no es necesario en un determinado contexto. Un hilo puede pasar por 4 etapas distintas: new, runnable, not running y dead. El campo de acción de un hilo se encuentra en la etapa runnable, que representa la ejecución del hilo y el subproceso que lo compone. 3 Facultad de Ingenierı́a Programación Orientada a Objetos Figura 3: Diagrama de representación del ciclo de vida de un hilo. Un hilo se encuentra en el estado new al momento de ser creado y permanece en ese estado hasta que el método start es llamado. Se encuentran inicializados y esperan la respectiva notificación para iniciar su ejecución. Cuando el método start es invocado en un hilo nuevo, el método run es llamado y el hilo pasa al estado runnable y el hilo comenzará a operar. El estado not running implica el bloqueo o la detención de un hilo. Los hilos pueden pasar a este estado por medio de los métodos suspend, sleep y wait, ası́ como por un bloqueo de I/0. Dependiendo de la forma en que el hilo pasó a este estado, un hilo puede regresar al estado runnable de las siguiente maneras: 1. Si un hilo se encuentra suspendido se utiliza el método resume. 2. Si un hilo estádurmiendo, se mantendrá en ese estado el número de milisegundos que se especi- fique. 3. Si un hilo está en estado de espera, pasará al estado runnable cuando se realice una llamada por medio de los métodos notify o notifyAll. 4. Si un hilo queda bloqueado por I/0, regresará a su anterior estado cuando la operación I/O pendiente sea completada. El estado dead en un hilo implica que el hilo en cuestión ya no es un objeto necesario y se descarta su uso. Los hilos en este estado no pueden volver a ejecutarse. Un hilo puede entrar en este estado por dos razones: El método run del mismo termina su ejecución o se realiza una llamada al método stop. 4 Facultad de Ingenierı́a Programación Orientada a Objetos 3.3. Planificador Java tiene un Planificador (Scheduler) que controla todos los hilos que se están ejecutando en todos sus programas y decide cuáles deben ejecutarse (dependiendo de su prioridad) y cuáles deben encontrarse preparados para su ejecución. 3.4. Prioridad Cada hilo tiene una determinada prioridad, la cual queda representada por un valor entero entre 1 y 10; de modo que cuanto mayor es el valor, mayor es su prioridad de ejecución. El planificador determina qué hilo debe ejecutarse en función de la prioridad asignada. Cuando se crea un hilo en Java, éste hereda la prioridad de su padre. Una vez creado el hilo es posible modificar su prioridad en cualquier momento utilizando el método setPriority. 4. Clase Thread La clase Thread es la responsable de producir hilos funcionales para otras clases. Para añadir la funcionali- dad de hilo a una clase se hereda de ésta. Esta clase posee el método run, el cual define la acción de un hilo y, por lo tanto, se conoce como el cuerpo del hilo. También define los métodos start y stop, los cuales permiten iniciar y detener la ejecución del hilo. Por lo tanto, para añadir la funcionalidad deseada a cada hilo es necesario redefinir el método run. Este método es invocado cuando se inicia el hilo. Un hilo se inicia mediante una llamada al método start de la clase Thread. El hilo se inicia con la llamada al método run y finaliza cuando termina este método llega a su fin. El siguiente es un ejemplo de la clase Thread: Este programa consta de tres hilos (el de el main, el Primer hilo y el Segundo hilo), dos de estos, mediante un ciclo for crearan sus iteraciones hasta finalizarlas imprimiendo su término en pantalla. 5Facultad de Ingenierı́a Programación Orientada a Objetos Figura 4: Ejemplo del uso de la clase Thread. Figura 5: Salida obtenida con el ejemplo anterior. 4.1. Interfaz Runnable En Java no está permitida la herencia múltiple, al menos de clases. La forma de solucionar este problema es utilizando una interfaz. Una forma de hacer programación paralela en Java sin heredar de la clase “Thread” es implementar la Interface “Runnable”. Este método es muy conveniente si queremos heredar de otra clase. 6 Facultad de Ingenierı́a Programación Orientada a Objetos La interfaz Runnable debe ser implementada por cualquier clase cuyas instancias sean ejecutadas por un hilo. Dicha clase debe implementar el método run. La implementación de la interface Runnable es la forma más habitual de crear tareas, ya que propor- ciona al desarrollador una forma para agrupar el trabajo de infraestructura de la clase. La interfaz establece el trabajo a realizar y la clase o clases que la implementan, indican cómo realizar ese trabajo. Se puede construir un hilo sobre cualquier objeto que implemente la interfaz Runnable. Para imple- mentar esta interfaz, una clase sólo tiene que implementar el método run. El código del uso de la interfaz Runnable y su respectiva prueba de escritorio se muestran a conti- nuación en el siguiente ejemplo: Figura 6: Salida obtenida con el ejemplo anterior. 4.2. ThreadDead La clase ThreadDeath proporciona un mecanismo para hacer limpieza después de que un hilo haya termi- nado de forma ası́ncrona. Un ejemplo de esto es cuando se invoca el método stop de un hilo, este se detiene de forma ası́ncrona, por lo tanto, se lanza una instancia de la clase threadDeath como un error, si es el caso de que el hilo ya no se siga ejecutando, se tendrá que eliminar y solo se podrá matar si se llama realmente a la clase . 7 Facultad de Ingenierı́a Programación Orientada a Objetos 4.3. ThreadGroup La clase threadGroup se utiliza para manejar un grupo de hilos de forma conjunta, lo cual nos da un medio para controlar de modo eficiente la ejecución de una serie de hilos ya que nos proporciona los métodos como lo son: stop, suspend y resume, donde si uno de estos es invocado, se invocará a todos los hilos pertenecientes al grupo. La utilidad que se le dio a la clase ThreadGroup en el código anterior fue cuando al grupo que consiste de 5 hilos, a todos les dio una prioridad normal con solo una lı́nea de código. Figura 7: Uso de la clase ThreadGroup. La utilidad que se le dio a la clase ThreadGroup en el código anterior fue cuando al grupo que consiste de 5 hilos, a todos les dio una prioridad normal con solo una lı́nea de código. 8 Facultad de Ingenierı́a Programación Orientada a Objetos Figura 8: El código se encarga de darle a cada hilo prioridad normal. (No se coloco toda la salida por su gran extensión). 4.4. Métodos o bloques sincronizados Los métodos sincronizados (synchronized) utilizan el cerrojo del objeto al que pertenecen evitando que más de un hilo entren en ellos al mismo tiempo. Todos los métodos synchronized de un mismo objeto comparten el mismo cerrojo, y es distinto al cerrojo de otros objetos. Estos métodos son muy utilizados en hilos (Threads) con la finalidad de no perder información o ambigüedad en ella misma. Los hilos se ejecutan como procesos independiente. Cuando se ejecutan de manera simultánea varios hilos, estos pueden llegar a acceder al mismo tiempo a otro método. Cómo se están ejecutando en paralelo (independientes), puede haber pérdida de información, ya que el recurso no está siendo controlado. Este problema se puede solucionar bloqueando el acceso al método mientras algún hilo o proceso se está ejecutando. Los más recomendable serı́a utilizar el método de sincronización. Un ejemplo de un método sincronizado es el siguiente: 9 Facultad de Ingenierı́a Programación Orientada a Objetos Figura 9: Uso de hilos en una simulación bancaria. Figura 10: Salida del ejemplo anterior. 10 Facultad de Ingenierı́a Programación Orientada a Objetos Del ejemplo anterior se puede llegar a la conclusión de que el programa en la práctica está mal el código, debido a que al parecer los hilos se están ejecutando de manera simultánea, por lo que a veces la salida (output) da valores diferentes en el saldo, además, el saldo final en cada cuenta debe ser de $50, lo cual no es. Otro factor en el cuál falla este programa es que no se puede llegar a comprender del todo las variables que incluyen este programa. En este siguiente ejemplo se corrigió el código para que funcionara adecuadamente: El anterior no funcionaba porque no se estaba usando un único objeto que tenga los métodos sincronizados. Realmente se están usando cuatro objetos y eso provoca que el acceso no se controle debidamente. Figura 11: Código corregido del ejemplo anterior. 11 Facultad de Ingenierı́a Programación Orientada a Objetos Figura 12: La salida resulta más razonable y más fácil de comprender. 5. Conclusiones A raiz del trabajo presentado la brigada pudo comprender la importancia que tiene la noción de hilos en la solución de problemas complejos que requieran el manejo de diversas operaciones de forma simultánea. Un aspecto importante a destacar es que los hilos no se ejecutan de una forma estructurada como suele ser en programas más sencillos, en cambio, la ejecución puede darse simultáneamente. Por otra parte, el control de la ejecución de los hilos resulta importante para obtener la salida desea- da. En el ejemplo abordado en la sección Métodos o bloques sincronizados se analizó un ejemplo con errores al momento de generar la salida. Por ello, se debe de ser cuidadoso al realizar programación con hilos para evitar tales errores. Finalmente, consideramos que esta aproximación inicial nos será de utilidad en asignaturas como Sistemas Operativos donde esta noción inicial se desarrolla más a fondo. Referencias [1] Hilos. Recuperado de: http://lcp02.fi-b.unam.mx/static/docs/PRACTICAS_POO/poo_p12. pdf. Fecha de consulta: 29/04/2020. Los créditos de las fotografı́as pertenecen a sus respectivos autores. c© LATEX 12 http://lcp02.fi-b.unam.mx/static/docs/PRACTICAS_POO/poo_p12.pdf http://lcp02.fi-b.unam.mx/static/docs/PRACTICAS_POO/poo_p12.pdf
Compartir