HILOS (Threads) Implementación en Java

Documentos relacionados
Arquitecturas cliente/servidor

Unidad IV: Programación concurrente (MultiHilos) 4.1. Concepto de hilo

Tema 6. Threads: programas multitarea

Guía práctica de estudio 12: Hilos

Guillermo Román Díez

Programación Concurrente y Paralela. Unidad 1 Introducción

Procesos y Threads Procesos y Threads. Concurrencia Concurrencia Ventajas Ventajas. Rendimiento Rendimiento (paralelismo) (paralelismo)

Cena de filosofos y sincronizacion java

Informática Electrónica Concurrencia

Hilos Secciones Stallings:

PROCESOS E HILOS - Hilo

Uso de recursos compartidos

de Gran Canaria Centro de Tecnología Médica Programación Concurrente

1. Fundamentos. Existen dos tipos distintos de multitarea: BASADA EN PROCESOS

Concurrencia. Primitivas IPC con bloqueo

Manipulación de procesos

cilred.com GESTIÓN DE TRANSACCIONES

Programación Concurrente Recopilación de teoría referente a la materia

Universisdad de Los Andes Facultad de Ingeniería Escuela de Sistemas

Concurrencia de Procesos

Concurrencia. Concurrencia

Procesos y Threads Procesos y Threads. Rendimiento Rendimiento (paralelismo) (paralelismo) Productividad Productividad

Procesos Definición y Estados

PARTE II PROGRAMACION CON THREADS EN C

Sistemas Operativos. Procesos

Unidad 3 Sistemas con memoria común

Tema 12: El sistema operativo y los procesos

Tarea 2. Descripción y Control de Procesos

Preguntas de autoevaluación tema 3

Tema III. Multihilo. Desarrollo de Aplicaciones para Internet Curso 12 13

Threads o Hilos. Un thread en JAVA comienza como una instancia de java.lang.thread antes de convertirse en un hilo de ejecución.

Concurrencia. Programación Concurrente Procesos Comunicación entre Procesos (IPC) con espera ocupada.

TEMA 3. CONCEPTOS FUNDAMENTALES DEL NIVEL DEL SISTEMA OPERATIVO. Definición y objetivos de un S.O

TAREA 1. INTRODUCCIÓN A LOS SISTEMAS OPERATIVOS.

Concurrencia y paralelismo

6. Enumere tres ventajas de los ULT frente a los KLT.

PARADIGMA y LENGUAJES DE PROGRAMACIÓN

Programación concurrente

Acceso coordinado a recursos compartidos

Participantes: Avila Aida Betancourt Sioly Briceño Susana Rojas Alejandro

STRINGBUFFER, STRINGBUILDER JAVA. EJEMPLO. DIFERENCIAS ENTRE CLASES. CRITERIOS PARA ELEGIR. MÉTODOS. (CU00914C)

Programación concurrente

PROCEDIMIENTOS ALMACENADOS

Capítulo 3. Procesos concurrentes 3.1. Conceptos de programación concurrente La computación concurrente es la simultaneidad en la ejecución de

T E M A 7. Interrupciones

PROGRAMACIÓN CONCURRENTE

Sistemas Operativos - Manejador de procesos - Fundamentos

Concurrencia. Programación Concurrente. Espera ocupada. Primitivas IPC con bloqueo

Sistemas operativos. Hasta ahora hemos visto. Relación programa-sistema operativo Gestión de memoria

Evolución del software y su situación actual

Sistemas Operativos. Dr. Luis Gerardo de la Fraga. Departamento de Computación Cinvestav

Transacciones y Control de concurrencia

Introducción a los Sistemas Operativos

Introducción a los Sistemas Operativos

Programación de Multitareas utilizando Hilos

Facultad de Ingeniería Industrial y de Sistemas v1.1 MA781U CONCEPTOS INICIALES CASOS DE USO

Introducción a los Sistemas Operativos S.O.

Cambio de hebra. Gustavo Romero. 13 de febrero de Arquitectura y Tecnología de Computadores. Voluntario Involuntario

SISTEMAS OPERATIVOS Capítulo 2 Concepto. Funciones.

Puebla, Pue a 4 de Junio del Programación Concurrente y Paralela

ISO Tema 8,

Aplicaciones Concurrentes

Aviso 2: Escriba con buena letra y evite los tachones. Aviso 3: Solución del examen y fecha de revisión en

Sistemas Operativos. Daniel Rúa Madrid

Tema 2. Administración de procesos

Laboratorio I Java Threads (Silberschatz Galvin)

7/1/18. Algoritmos RESOLVIENDO PROBLEMAS. Libro en línea. Cuál es el objetivo del libro? Ing. Roberto Martínez Román -

José Luis López Delgado* Gestión comercial con Velneo V7.1. Capitulo I. Instalación de las aplicaciones El entorno de trabajo

Convivencia Gestión de Procesos

Servicios del Sistema Operativo (SO)

Planificación de Monoprocesadores.

Ejercicios de Hilos. Índice

Sincronización de procesos

Estructura Windows NT

Programación Orientada a Objetos en C++

PROGRAMACIÓN PARALELA. Modelos de programación paralela Paradigmas de programación paralela

Porque desarrolló el concepto de lista de tareas (pool de Job) que podía ser gestionada de acuerdo a políticas distintas a la FIFO.

TEMARIO DEL CELADOR SERVASA SANIDAD DE LA COMUNIDAD VALENCIANA INFORMÁTICA HERRAMIENTAS DE ESTUDIO PARA CELADORES.

Ejecución de hebras. En realidad, todas las aplicaciones escritas en Java son aplicaciones multihebra (recuerde el recolector de basura).

SISTEMAS OPERATIVOS, 10 de septiembre de 2009 Examen Convocatoria Extraordinaria

SISTEMAS OPERATIVOS I (Sistemas) / SISTEMAS OPERATIVOS (Gestión) septiembre 2009

MULTIPROGRAMACIÓN. Introducción a al Multitarea

No obstante, incluso en los sistemas monolíticos es posible tener al menos un poco de estructura. Los servicios (llamadas al sistema) proporcionados

Programación Orientada a Objetos. Resumen de Temas Unidad 3: Constructores y destructores

Lenguajes de Programación

Práctica 4 Concurrencia en Java

Tema 1: Programación Multiproceso. Curso

Sincronización de Threads

ARQUITECTURA BÁSICA DEL ORDENADOR: Hardware y Software. IES Miguel de Cervantes de Sevilla

Tema 12: Programación multihilo

Tema II. Descripción y control de procesos. UNED Manuel Fernández Barcell. Blog:

Master en Java Certificación para Programadores

Esp. Alexis Olvany Torres ch. Datos de salida. Datos de salida. Datos de salida

Sistemas Operativos. Sistemas Operativos II ITS EMT CETP 2014 Prof. L. Carámbula

Ing. Félix Piozzi Sistemas Operativos UTN FRC

*** SOLUCIONES *** SISTEMAS OPERATIVOS Examen Parcial 24 de Abril de 2010

Normalmente, los programas son ejecutados de forma secuencial. Único flujo de control

Sistemas Complejos en Máquinas Paralelas

Transcripción:

HILOS (Threads) Implementación en Java

Multitarea Sería bueno si pudiéramos concentrar nuestra atención en realizar una sola acción a la vez, y realizarla bien, pero por lo general, eso es difícil. El cuerpo humano realiza una gran variedad de operaciones en paralelo, es decir, operaciones concurrentes. Por ejemplo, la respiración, la circulación de la sangre, la digestión, la acción de pensar y caminar pueden ocurrir de manera concurrente.

Las computadoras también pueden realizar operaciones concurrentes. Para las computadoras es tarea común compilar un programa, enviar un archivo a una impresora y recibir mensajes de correo electrónico a través de una red, de manera concurrente. Sólo las computadoras que tienen múltiples procesadores pueden realmente ejecutar varias instrucciones en forma concurrente. Los sistemas operativos en las computadoras con un solo procesador crean la ilusión de la ejecución concurrente, al alternar rápidamente entre una tarea y otra, pero en dichas computadoras sólo se puede ejecutar una instrucción a la vez.

La mayoría de los lenguajes de programación no permiten a los programadores especificar actividades concurrentes. Por lo general, los lenguajes proporcionan instrucciones de control secuenciales, las cuales permiten a los programadores especificar que sólo debe realizarse una acción a la vez, en donde la ejecución procede a la siguiente acción una vez que la anterior haya terminado.

Java pone las primitivas de concurrencia a disposición del programador de aplicaciones, a través del lenguaje y del API. El programador especifica que una aplicación contiene subprocesos de ejecución separados, en donde cada subproceso o tarea tiene su propia pila de llamadas a métodos y su propio contador, lo cual le permite ejecutarse concurrentemente con otras tareas, al mismo tiempo que comparte los recursos a nivel de aplicación (como la memoria) con estos otros subprocesos.

A diferencia de los lenguajes que no tienen capacidades integradas de multitarea (como C y C++) y que, por lo tanto, deben realizar llamadas no portables a las primitivas de multitarea del sistema operativo, Java incluye las primitivas de multitarea como parte del mismo lenguaje y como parte de sus bibliotecas. Esto facilita la manipulación de las tareas de una manera portable entre plataformas.

Aplicaciones Existen muchas aplicaciones de la programación concurrente, paralela o multitarea. Por ejemplo, cuando se descarga un archivo extenso (como una imagen, un clip de audio o video) a través de Internet, tal vez el usuario no quiera esperar hasta que se descargue todo un video completo para empezar a reproducirlo. Para resolver este problema podemos poner varios subprocesos a trabajar; uno para descargar el video y otro para reproducirlo. Estas actividades se llevan a cabo en paralelo. Para evitar que la reproducción del video tenga interrupciones, sincronizamos (coordinamos las acciones de) los subprocesos de manera que la tarea de reproducción no empiece sino hasta que haya una cantidad suficiente del video en memoria, como para mantener ocupado al subproceso de reproducción.

Multitarea en Java La Máquina Virtual de Java (JVM) utiliza subprocesos también. Además de crear tareas para ejecutar un programa, la JVM también puede crear subprocesos para llevar a cabo tareas de mantenimiento, como la recolección de basura. Escribir programas con subprocesamiento múltiple puede ser un proceso complicado. Aunque la mente humana puede realizar funciones de manera concurrente, a las personas se les dificulta saltar de un tren paralelo de pensamiento al otro.

Para ver por qué los programas con multitarea pueden ser difíciles de escribir y comprender, pensemos en el siguiente experimento: Abrir tres libros en la página 1 y tratar de leerlos concurrentemente. Leer unas cuantas palabras del primer libro; después unas cuantas del segundo y por último otras cuantas del tercero. Luego, regresar a leer las siguientes palabras del primer libro, etcétera. Después de este experimento se puede apreciar muchos de los retos que implica la multitarea: alternar entre los libros, leer brevemente, recordar en dónde se quedó en cada libro, acercar el libro que está leyendo para poder verlo, hacer a un lado los libros que no está leyendo y, entre todo este caos, tratar de comprender el contenido de cada uno!

Hilos o Threads Una aplicación multitarea es capaz de ejecutar más de un proceso simultáneamente. Un thread o hilo es un flujo secuencial simple (un fragmento de código coherente) dentro de un proceso. Un único proceso puede tener varios hilos ejecutándose. Los threads o hilos de ejecución permiten organizar los recursos de forma que pueda haber varios procesos actuando en paralelo. Idealmente, una vez que tiene una cierta cantidad mínima de información inicial, un thread puede ejecutarse de principio a fin sin ninguna información adicional del mundo exterior. Idealmente, threads diferentes son independientes.

Ejemplo: Si queremos ver un listado de 100 imágenes que se descargan desde Internet, como usuario Cuál de las dos opciones siguientes elegirías? A) Descargar las imágenes 100 imágenes, haciendo esperar al usuario con una pantalla de cargando hasta que se descargan todas. Luego podrá ver el listado con las imágenes. B) Que mientras se descargan las 100 imágenes, el usuario pueda ir viendo y usando las que ya se han descargado.

Ejemplo SIN multitarea Primero busca todos los paquetes de datos con las imágenes de una fábrica que se llama Internet. Lleva todos estos paquetes en camión y los descarga a una tienda llamada dispositivo del usuario.

Luego le toca colocar todo y cada uno de los paquetes que ha trasportado al escaparate de la tienda, que para aclarar también podemos llamar como pantalla del dispositivo. Todo esto se hace con la finalidad de que el cliente o usuario los consuma. Eso sí, solo en este momento se le permite al usuario poder consumirlos (ya que es el momento que tiene algo que consumir, antes no había nada) con lo que el resto del tiempo estuvo esperando.

Ejemplo CON multitarea Para empezar, el trabajador/hilo en segundo plano toma algún paquete de datos de la fábrica que llamamos Internet, lo lleva en camión y lo descarga en la tienda. Donde el trabajador/hilo principal está esperando a que le llegue algún paquete para poder realizar su labor. El trabajador/hilo principal ya tiene algo que hacer. Toma el paquete que le ha llegado y lo coloca en el escaparate de la tienda (que hemos llamado casualmente como pantalla del dispositivo ). Mientras tanto, el trabajador/hilo en segundo plano no ha terminado su trabajo, con lo que continúa llevando paquetes a la tienda desde la fábrica. Cabe notar, que ha sido dicho y hecho, el cliente/usuario ya tiene al menos un paquete que consumir en la tienda.

El proceso continúa. El trabajador/hilo en segundo plano lleva a la tienda los paquetes, para que el trabajador/hilo en primer plano los coloque en el escaparate. Por lo que, el cliente/usuario puede ir consumiendo cuanto desee de lo que exista ya en el escaparate. Esto durará hasta que se cumpla alguna condición de finalización o interrupción de algún trabajador/hilo, las cuales pueden ser muchas (por ejemplo: apagar el dispositivo, que se hayan acabado los paquetes que descargar, etc).

Para el primer ejemplo (SIN multitarea), en el que solo existe un hilo principal que lo hace todo tenemos que todo se hace en un tiempo X que se estima largo. Podemos representar por la siguiente barra de tiempo desde el principio de la ejecución del hilo hasta el fin. En comparación con el segundo ejemplo, en el que ya tenemos dos hilos, uno principal y otro secundario, que trabajan de manera simultánea. Es deducible que el tiempo que tarda en hacerse todo el proceso es bastante menor, ya que se sobrexponen los tiempos de ambos hilos. En la siguiente representación vemos como el hilo principal se ejecuta de manera paralela al hilo en segundo plano y que es menos a la anterior barra de tiempo.

Pero todos los hilos que pueden ejecutarse en paralelo se ejecutan todos a la vez? No siempre. Depende de un factor delimitador más a tener en cuenta, que aunque no lo controla el desarrollador de aplicaciones existe siempre: el procesador. Sabiendo que el procesador es el encargado de ejecutar los programas. Y que un procesador puede tener entre un núcleo y muchos. Sirviendo los núcleos para procesar de manera simultánea varios hilos. Esto es, cada núcleo ejecuta un hilo a la vez. Por lo que si tenemos un procesador con dos núcleos, podremos ejecutar dos hilos a la vez. Si tenemos uno de cuatro núcleos podrá ejecutar un máximo de cuatro hilos de manera simultánea. Y así con todos los núcleos de los que dispongamos.

Siguiendo con el ejemplo, con los trabajadores que son hilos, el núcleo sería el cerebro de cada trabajador/hilo. Un trabajador/hilo siempre tendrá una misión que hacer determinada, pero sin un cerebro/núcleo no puede hacer nada. (Equiparamos al núcleo de un procesador con el cerebro). Así, en el primer ejemplo de la fábrica y la tienda con un solo trabajador/hilo, con un cerebro/núcleo le es más que suficiente para ejecutar todo de manera correcta. Le sobraría con un procesador con un núcleo, pues más núcleos no los aprovecharía. Por lo que un cerebro/núcleo procesará el trabajo tan rápido como pueda en el tiempo (Esta rapidez se mide con la velocidad de reloj de un núcleo de un procesador, es decir, los Hz.).

El segundo ejemplo es más complejo. Estamos suponiendo que tenemos dos núcleos. Si nos fijamos en los cerebros/núcleos, podemos llegar a la conclusión que existen dos núcleos, uno por cada hilo que se ejecuta. Así, con dos cerebros/núcleos se puede trabajar en paralelo.

Pero también se puede dar lo siguiente con el segundo ejemplo: Qué ocurriría si tenemos un procesador con un único núcleo? Qué hilo se ejecutaría? Uno primero y otro después? Dará error la aplicación? Qué hará?

Es evidente que no hay suficientes cerebros/núcleos para tantos trabajadores/hilos. En algún momento uno de ellos no tendrá cerebro/núcleo y se tendrá que quedar detenido completamente mientras el otro con cerebro/núcleo realiza sus labores. Lo razonable y justo es que compartan el cerebro/núcleo un rato cada uno para poder trabajar los dos. Y así es como se hace. El procesador se encarga de decidir cuánto tiempo va a usar cada hilo el único núcleo que existe. Dicho de otro modo, el procesador partirá los hilos en cachos muy pequeños y los juntará salteados en una línea de tiempo. Al procesarse los dos hilos de manera salteada, y gracias a la gran velocidad con la que procesan datos los procesadores, dará la sensación de paralelismo, pero no es paralelismo. No es paralelo pero sí es concurrente.

Estados de un hilo En cualquier momento dado, se dice que un hilo se encuentra en uno de varios estados.

Un nuevo hilo empieza su ciclo cuando hace la transición al estado nuevo; permanece en este estado hasta que el programa inicia el hilo, con lo cual se coloca en el estado ejecutable. Se considera que un hilo en el estado ejecutable está ejecutando su tarea. Algunas veces, un hilo ejecutable cambia al estado en espera mientras espera a que otro hilo realice una tarea. Un hilo en espera regresa al estado ejecutable sólo cuando otro hilo notifica al hilo esperando que puede continuar ejecutándose.

Un hilo ejecutable puede entrar al estado en espera sincronizado durante un intervalo específico de tiempo. Regresa al estado ejecutable cuando ese intervalo de tiempo expira, o cuando ocurre el evento que está esperando. Los hilo en espera sincronizado y en espera no pueden usar un procesador, aun cuando haya uno disponible.

Un hilo ejecutable puede cambiar al estado en espera sincronizado si proporciona un intervalo de espera opcional cuando está esperando a que otro hilo realice una tarea. Dicho hilo regresa al estado ejecutable cuando se lo notifica otro hilo, o cuando expira el intervalo de tiempo; lo que ocurra primero. Otra manera de colocar a un hilo en el estado en espera sincronizado es dejar inactivo un hilo ejecutable.

Un hilo inactivo permanece en el estado en espera sincronizado durante un periodo designado de tiempo (conocido como intervalo de inactividad), después del cual regresa al estado ejecutable. Los hilos están inactivos cuando, en cierto momento, no tienen una tarea que realizar. Un hilo ejecutable cambia al estado bloqueado cuando trata de realizar una tarea que no puede completarse inmediatamente, y debe esperar temporalmente hasta que se complete esa tarea. Por ejemplo, cuando un hilo emite una petición de entrada/salida, el sistema operativo bloquea el hilo para que no se ejecute sino hasta que se complete la petición de E/S; en ese punto, el hilo bloqueado cambia al estado ejecutable, para poder continuar su ejecución. Un hilo bloqueado no puede usar un procesador, aun si hay uno disponible.

Un hilo ejecutable entra al estado terminado (algunas veces conocido como el estado muerto) cuando completa exitosamente su tarea, o termina de alguna otra forma (tal vez debido a un error). A nivel del sistema operativo, el estado ejecutable de Java generalmente abarca dos estados separados.

El sistema operativo oculta estos estados de la Máquina Virtual de Java (JVM), la cual sólo ve el estado ejecutable. Cuando un hilo cambia por primera vez al estado ejecutable desde el estado nuevo, el hilo se encuentra en el estado listo. Un hilo listo entra al estado en ejecución (es decir, empieza su ejecución) cuando el sistema operativo lo asigna a un procesador; a esto también se le conoce como despachar el hilo. En la mayoría de los sistemas operativos, a cada hilo se le otorga una pequeña cantidad de tiempo del procesador (lo cual se conoce como quantum o intervalo de tiempo) en la que debe realizar su tarea.

Cuando expira su quantum, el hilo regresa al estado listo y el sistema operativo asigna otro hilo al procesador. Las transiciones entre los estados listo y en ejecución las maneja únicamente el sistema operativo. La JVM no ve las transiciones; simplemente ve el hilo como ejecutable y deja al sistema operativo la decisión de cambiar el hilo entre listo y ejecutable. El proceso que utiliza un sistema operativo para determinar qué hilo debe despachar se conoce como programación de hilos o subprocesos, y depende de las prioridades de los hilos.

Prioridades Todo hilo en Java tiene una prioridad, la cual ayuda al sistema operativo a determinar el orden en el que se programan los hilos. Las prioridades de Java varían entre MIN_PRIORITY (una constante de 1) y MAX_PRIORITY (una constante de 10). De manera predeterminada, cada hilo recibe la prioridad NORM_PRIORITY (una constante de 5). Cada nuevo subproceso hereda la prioridad del subproceso que lo creó.

De manera informal, los hilos de mayor prioridad son más importantes para un programa, y se les debe asignar tiempo del procesador antes que a los hilos de menor prioridad. Sin embargo, las prioridades de los hilos no garantizan el orden en el que se ejecutan los hilos. El programador de subprocesos de un sistema operativo determina cuál hilo se debe ejecutar a continuación. Una implementación simple del programador de subprocesos mantiene el hilo de mayor prioridad en ejecución en todo momento y, si hay más de un hilo de mayor prioridad, asegura que todos esos hilos se ejecuten durante un quantum cada uno, en forma cíclica (round-robin).

Java cuenta con herramientas de concurrencia de alto nivel para ocultar parte de esta complejidad, y hacer que los programas sean menos propensos a errores. Las prioridades de los hilos se utilizan en segundo plano para interactuar con el sistema operativo, pero la mayoría de los programadores que utilizan multi-hilos en Java no tienen que preocuparse por configurar y ajustar las prioridades de los hilos.

Creación de Hilos En Java hay dos formas de crear nuevos threads: La primera de ellas consiste en crear una nueva clase que herede de la clase java.lang.thread y sobrecargar el método run( ) de dicha clase. El segundo método consiste en declarar una clase que implemente la interface java.lang.runnable, la cual declarará el método run( ); posteriormente se crea un objeto de tipo Thread pasándole como argumento al constructor el objeto creado de la nueva clase (la que implementa la interface Runnable). Thread y Runnable pertenecen al package java.lang

Ejemplo usando Thread Hilos

Ejemplo usando Runnable

Ejemplo Hilos

Sincronización Cuando varios hilos comparten un objeto, y éste puede ser modificado por uno o más de los hilos, pueden ocurrir resultados indeterminados, a menos que el acceso al objeto compartido se administre de manera apropiada. Si un hilo se encuentra en el proceso de actualizar a un objeto compartido, y otro hilo trata de actualizarlo también, no queda claro cuál actualización del hilo se lleva a cabo. Cuando esto ocurre, el comportamiento del programa no puede determinarse; algunas veces el programa producirá los resultados correctos; sin embargo, en otras ocasiones producirá los resultados incorrectos. En cualquier caso, no habrá indicación de que el objeto compartido se manipuló en forma incorrecta.

El problema puede resolverse si se da a un hilo a la vez el acceso exclusivo al código que manipula al objeto compartido. Durante ese tiempo, otros hilos que deseen manipular el objeto deben mantenerse en espera. Cuando el hilo con acceso exclusivo al objeto termina de manipularlo, a uno de los hilos que estaba en espera se le debe permitir que continúe ejecutándose. Este proceso, conocido como sincronización, coordina el acceso a los datos compartidos por varios hilos concurrentes.

Al sincronizar los hilos de esta forma, podemos asegurar que cada hilo que accede a un objeto compartido excluye a los demás hilos de hacerlo en forma simultánea; a esto se le conoce como exclusión mutua. Una manera de realizar la sincronización es mediante los monitores integrados en Java. Cada objeto tiene un monitor y un bloqueo de monitor (o bloqueo intrínseco). El monitor asegura que el bloqueo de monitor de su objeto se mantenga por un máximo de sólo un hilo a la vez.

Así, los monitores y los bloqueos de monitor se pueden utilizar para imponer la exclusión mutua. Si una operación requiere que el hilo en ejecución mantenga un bloqueo mientras se realiza la operación, un hilo debe adquirir el bloqueo para poder continuar con la operación. Otros hilos que traten de realizar una operación que requiera el mismo bloqueo permanecerán bloqueados hasta que el primer hilo libere el bloqueo, punto en el cual los hilos bloqueados pueden tratar de adquirir el bloqueo y continuar con la operación.

Para especificar que un hilo debe mantener un bloqueo de monitor para ejecutar un bloque de código, el código debe colocarse en una instrucción synchronized. Se dice que dicho código está protegido por el bloqueo de monitor; un hilo debe adquirir el bloqueo para ejecutar las instrucciones synchronized. El monitor sólo permite que un hilo a la vez ejecute instrucciones dentro de bloques synchronized que se bloqueen en el mismo objeto, ya que sólo un hilo a la vez puede mantener el bloqueo de monitor.

Cuando una instrucción synchronized termina de ejecutarse, el bloqueo de monitor del objeto se libera y el sistema operativo puede permitir que uno de los hilos bloqueados, que intentan entrar a una instrucción synchronized, adquieran el bloqueo para continuar. Java permite los métodos synchronized. Dicho método es equivalente una instrucción synchronized que encierra el cuerpo completo de un método, y que utiliza a this como el objeto cuyo bloqueo de monitor se va a adquirir. Para especificar un método como synchronized se coloca la palabra reservada synchronized antes del tipo de valor de retorno del método en su declaración.

LABORATORIO