PDF de programación - 4.Concurrencia de memoria común en Java

Imágen de pdf 4.Concurrencia de memoria común en Java

4.Concurrencia de memoria común en Javagráfica de visualizaciones

Publicado el 14 de Diciembre del 2018
179 visualizaciones desde el 14 de Diciembre del 2018
394,9 KB
40 paginas
Creado hace 9a (13/03/2011)
4.Concurrencia de memoria común en Java

INTRODUCCIÓN

Historia de la concurrencia

4.1
4.1.1
Los sistemas operativos han evolucionado hasta permitir la ejecución de más de un
programa de forma simultánea, en procesos individuales, aislados a los que el sistema
operativo les asigna los recursos (memoria, descriptores de archivo, etc.). Los procesos
pueden comunicarse con los demás procesos si fuera necesario a través de los
mecanismos de comunicación que proporciona el sistema operativo: sockets,
manejadores de señales, memoria compartida, semáforos y archivos.

Los motivos que llevaron a desarrollar sistemas operativos que permitiera la ejecución
simultánea de varios programas son:

- Uso de recursos:

Cuando un programa está a la espera de un recurso de E/S está

El sistema operativo asigna el mismo tiempo de uso de CPU a todos los


desperdiciando tiempo de CPU.
Justicia:

procesos y usuarios.

Es más fácil escribir varios programas que cumplan una única
tarea y coordinarlos antes que tener un solo programa que se encargue de todas
las tareas.

-

- Conveniencia:

Las mismas preocupaciones que motivaron el desarrollo de los procesos ha motivado el
desarrollo de los hilos. Los hilos comparten recursos como la memoria y los
descriptores de archivos, pero cada hilo tiene su propio contador de programa, su propia
pila y sus variables locales. Además permiten el paralelismo en sistemas
multiprocesador, múltiples hilos del mismo programa pueden ser ejecutados
simultáneamente en múltiples CPUs.

A los hilos también se les conoce como “procesos ligeros”, y los sistemas operativos
modernos tratan con hilos como unidad básica de programación. En la ausencia de
coordinación explícita, los hilos se ejecutan de forma simultánea y asíncrona respecto a
los demás, sin embargo, es necesario coordinar el acceso a los datos compartidos ya
que, un hilo puede querer modificar una variable mientras está siendo utilizada por otro
obteniendo resultados inesperados.

Beneficios de los hilos.

4.1.2
Cuando se usan correctamente los hilos pueden reducir costes de desarrollo y
mantenimiento además de mejorar el rendimiento de la aplicación.

1.2.1. Aprovechamiento de múltiples procesadores.
Los sistemas multiprocesador son cada vez más comunes, ya que cada vez es más
difícil aumentar la velocidad del procesador y más fácil añadir más procesadores.
Cada procesador puede ejecutar como máximo un programa a la vez, en cambio, un
programa compuesto por múltiples hilos puede ser ejecutado en varios procesadores
simultáneamente, pudiendo así aumentar el rendimiento de la aplicación.
También se puede lograr un mejor rendimiento de la aplicación usando hilos sobre
sistemas con un solo procesador. Mientras un hilo se queda esperando por una
operación síncrona (E/S) otro hilo puede ejecutarse permitiendo que la aplicación siga
ejecutándose durante el bloqueo E/S.

1.2.2. Simplicidad de modelado.
Es más fácil escribir programas que ejecuten un solo tipo de tarea secuencialmente, más
sencillo de probar y de mantener que múltiples tipos de tareas a la vez. Asignando a
cada hilo un tipo de tarea se puede simplificar el código. Un flujo de trabajo complejo y
asíncrono puede descomponerse en varios flujos simples y síncronos cada uno de los
cuales ejecutados en hilos distintos, interactuando unos con otros en puntos concretos.
Un ejemplo de esto es el RMI (Remote Method Invocation), que puede gestionar
múltiples peticiones de forma simultánea.

1.2.3. Manejo simplificado de eventos asíncronos.
Los servidores deben ser capaces de aceptar múltiples conexiones de los clientes y con
cada uno debe establecer un canal de comunicación, cuando se espera recibir datos de
un cliente, todo el servidor se bloquea, para evitar esto se forzó a usar operaciones de
E/S no bloqueantes, lo que aumentaba el número de errores de la aplicación además ser
más complejo que la comunicación síncrona. Otra solución para solventar este problema
son los hilos, si para cada conexión se crea un hilo, cuando se espera la recepción de
datos sólo quedaría bloqueado el hilo en cuestión, y no todo el servidor.

1.2.4. Interfaces de usuario más sensibles.
Utilizando interfaces gráficas de usuario con un solo hilo se presentaban problemas
como la aparente “congelación” de la interfaz o que los controles de la interfaz podían
quedar inservibles durante un cierto tiempo ya que al ser un solo hilo, hasta que no
terminaba la tarea que estuviera ejecutando, no devolvía el control a la interfaz.
Las interfaces modernas como AWT y Swing no tienen este problema ya que,
reemplazan el bucle de eventos con un gestor de eventos, quedando así la interfaz
siempre activa y funcional. La interfaz es la que se encargaría de gestionar los hilos, no
sería un único bucle encargado de hacer todas las tareas como en el caso de un solo hilo.

Riesgos de los hilos.

4.1.3
1.3.1. Peligros de seguridad
Los hilos pertenecientes a una misma tarea comparten direcciones de memoria y se
ejecutan concurrentemente, esto es una gran ventaja porque hace que la compartición
sea mucho más sencilla de lo que sería con otros mecanismos de comunicación, pero
tiene un inconveniente, y es que el acceso simultáneo a las variables por parte de los

hilos puede provocar valores inesperados, es decir, el resultado del programa dependería
del orden de acceso a la variable, lo que se conoce como condiciones de carrera.
Para evitar esto, Java proporciona mecanismos de sincronización que permite a los hilos
acceder a las variables de uno en uno, evitando las condiciones de carrera. Para esto,
los hilos no han de modificar la variable directamente, sino que han de hacer uso de un
método “synchronized” que modifique el valor de la variable, y este método será quien
llevará la sincronización de los hilos.

1.3.2. Bloqueo mutuo.
El bloqueo mutuo se produce cuando un hilo A está esperando por los recursos que
posee un hilo B y éste no los libera, por tanto el hilo A se quedará en un bucle de espera
infinito y nunca progresará en su ejecución.

1.3.3. Peligros de rendimiento.
Los hilos tienen un coste de rendimiento adicional debido a los mecanismos de
sincronización necesarios, a que la gestión de programas con varios hilos por parte del
procesador es más costosa que de los programas con un solo hilo, y estos factores
añaden
rendimiento.

adicional

coste

de



un



Los hilos están por todas partes.

4.1.4
Incluso cuando un programa no crea explícitamente hilos, los frameworks pueden
crearlos en tu nombre, y esos hilos también deben ser “seguros”. Todas las aplicaciones
de Java usan hilos: el hilo que ejecuta el método main, los hilos correspondientes a
AWT y Swing, etc.
Algunas facilidades para hacer seguros los hilos (desde el propio código no desde la
aplicación principal) son los siguientes:

- Timer:
-

Es un mecanismo de gestión de tareas a ejecutar.


Estos frameworks están diseñados para
Servlets y JavaServer Pages (JSPs):

manejar el despliegue de aplicaciones web y manejar las peticiones remotas de
clientes HTTP.

Swing y AWT:

Gestionan acciones asíncronas, es decir, es capaz de controlar las
acciones llevadas a cabo por el usuario mientras la aplicación está haciendo
algo.

Permite ejecutar métodos que se están ejecutando remotamente.

- RMI:
-

SEGURIDAD EN HILOS (THREAD-SAFETY)

4.2
Los hilos y los bloqueos en la programación concurrente no distan mucho de lo que son
las vigas y remaches para un ingeniero de obras públicas. Esto viene a decir, que en la
construcción de un puente, para que éste no se caiga, se requiere un correcto uso de una
gran cantidad de vigas y remaches. Esto mismo ocurre en la programación concurrente
con los hilos y bloqueos, ya que se requiere un correcto uso de ellos para manejar el
acceso a un estado, y en concreto, para compartir dichos estados variables.
Hablamos de hilos-seguros como si fuera código, pero lo que realmente intentamos
hacer es proteger los datos de un acceso concurrente no controlado. Es una propiedad de
cómo se utiliza el objeto en un programa, no de lo qué hace.
Si más de un hilo accede a un estado variable, y cualquiera de ellos puede modificarlo,
se deben coordinar sus accesos usando sincronización.

4.2.1
Definiciones:

Qué es un thread safety

- Thread-safe describe parte de código o rutina que puede ser llamada desde
múltiples hilos programados sin querer tener ningún tipo de interacción entre
ellos.

- Debe satisfacer la necesidad de que múltiples threads accedan a los mismos
datos compartidos, y la necesidad de que una pieza compartidad de datos sea
accedida por solo un thread en un momento dado.

Atomicidad

4.2.2
Si queremos crear un contador en nuestro código para calcular el número de peticiones
recibidas, si lo implementamos de la siguiente manera:
public void contador(){
}

count++;

será una única operación pero no atómica, es decir, no se ejecutará como una simple e
indivisible operación ya que realmente se divide en una secuencia de 3 operaciones
atómicas: leer el valor, sumarle 1 y escribir el nuevo valor. De esta forma, se puede dar
el caso de que varios procesos accedan al mismo tiempo al recurso compartido,
cambiando su estado y obteniendo de esta forma un valor no esperado de la misma. Esto
es lo que conocemos como condiciones de carrera.

Bloqueo

4.2.3
En java hay un mecanismo para forzar la atomicidad: el bloque síncrono. El bloque
síncrono consta de dos partes: una referencia a un objeto que servirá como bloqueo y un
bloque de código que deberá de proteger el bloqueo.
Los bloqueos en Java como mutex o exclusión mutua permiten que al menos un hilo
acced
  • Links de descarga
http://lwp-l.com/pdf14539

Comentarios de: 4.Concurrencia de memoria común en Java (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios
Es necesario revisar y aceptar las políticas de privacidad