Programación B
Programación Orientada a Objetos
Ingeniería en Informática
Universidad FASTA
Ing. Luis Buffoni
Lic. Claudio Gea
POO en Java: Programación Multihilos
Universidad FASTA – Programación B 1
Programación Multihilos
Conceptos
Implica “hacer más de una cosa al mismo tiempo”
Hay ocasiones en que necesitamos que el programa realice
paralelamente algún proceso que no interfiera en la aplicación
principal:
Atender lo que se recibe por un Socket,
Traspasar gran cantidad de datos de una tabla a otra, etc.
Browsers: Carga de imágenes en segundo plano
Programación multithreading
– Consiste en conmutar entre distintas partes del código de un mismo
programa durante la ejecución.
– Cada una de estas partes individuales y atómicas (no divisibles) se
llama hilo (thread)
– Posibilita, por ejemplo, que la entrada en bucles largos o la ejecución
de procesos pesados o de tareas que pueden hacerse en segundo
plano, no paralicen la aplicación
Universidad FASTA – Programación B 2
Programación Multihilos
Procesos e Hilos
Proceso = Código + Pila + Heap
La conmutación entre procesos resulta una tarea lenta y
pesada respecto a la conmutación entre hilos que, a
pesar de poseer cada uno su propia pila y conjunto de
registros, comparten recursos: espacio de memoria,
archivos abiertos, etc. (mismo heap)
Los hilos existen dentro de un proceso, todo proceso
tiene al menos uno llamado Hilo Primario
Podemos crear nuevos hilos al proceso, que pueden
ejecutarse paralelamente al hilo primario
La comunicación entre hilos es más eficiente que entre
procesos, pero puede generar ciertos problemas de
sincronización si usan recursos compartidos
Universidad FASTA – Programación B 3
Programación Multihilos
Threads en Java
Java utiliza en su API programación concurrente que suele ser
transparente para el desarrollador (ej, método service en Servlets,
Garbage Collector).
En Java, una instancia de la clase java.lang.Thread representa un
hilo de proceso. Este objeto se emplea para iniciar, detener o cancelar la
ejecución del hilo.
La clase Thread ofrece un método run() que contiene el código que se
desea ejecutar en el hilo
También puede hacerse mediante una clase que implemente la interface
java.lang.Runnable, que define un método llamado run() que inicia
la vida del hilo. Esta opción es más flexible, porque permite que la clase
descienda de otra que no sea Thread.
Universidad FASTA – Programación B 4
Programación Multihilos
Estados de un Hilo
Universidad FASTA – Programación B 5
Programación Multihilos
Métodos de la clase Thread
start()
Un hilo de proceso que acaba de crearse permanece inactivo
hasta que se ejecuta su método start()
Solamente se puede llamar una vez a este método durante el
ciclo de vida de un hilo.
Un hilo sigue ejecutándose hasta que suceda alguna de las
siguientes cosas:
se acabe de ejecutar el código contenido en el método run().
se produzca una excepción sin capturar durante la ejecución.
se llame de manera explícita al método stop() (no aconsejable).
Si no ocurre ninguna de estas tres cosas, el hilo continúa ejecutándose,
incluso después de que la aplicación que lo creó haya terminado.
Universidad FASTA – Programación B 6
Programación Multihilos
Métodos de la clase Thread
Thread.sleep: método estático que causa la suspensión del hilo
corriente por un periodo especificado
Se usa para generar tiempo de procesador disponible, o esperar a otro hilo.
Puede generar una InterruptedException cuando otro hilo interrumpe el hilo
“dormido”.
interrupt: indica a un hilo que detenga lo que está haciendo. El
programador debe decidir cómo el hilo responderá a una interrupción
(generalmente su terminación).
join: permite a un hilo esperar por la terminación de otro. Puede generar una
InterruptedException
setPriority: cambia la prioridad del hilo
Universidad FASTA – Programación B 7
Programación Multihilos
Precauciones (I)
Si bien los hilos otorgan importantes ventajas, deben usarse sólo
cuando sean imprescindibles, en procesos realmente críticos y/o
importantes:
– Suman complejidad y pueden llegar a comerse el procesador (incrementan
uso del CPU)
– Son difíciles de debuggear
Las secciones de código potencialmente peligrosas por el uso de
recursos compartidos se conocen como secciones críticas
Las secciones críticas deben ser lo más pequeñas posible de
forma que los mecanismos de protección no degraden el
funcionamiento del sistema
Universidad FASTA – Programación B 8
Programación Multihilos
Precauciones (II)
Se debe evitar...
… que varios hilos entren en una sección crítica simultáneamente para
que no haya vistas inconsistentes de la memoria compartida
Solución → exclusión mutua o mutex (sincronización de métodos u objetos)
mediante el uso de la palabra reservada synchronized:
Basta con declarar un método como synchronized para que dos o más hilos no
puedan ejecutar dicho método sobre el mismo objeto a la vez.
La sincronización en Java está basada en una entidad interna: “lock intrínseco” o
monitor.
Se puede afinar más la exclusión y evitar el acceso simultáneo a nivel de un
fragmento de código, también mediante la palabra reservada synchronized
synchronized(this.b) {
System.out.println("Thread " + this.getName() + " ha bloqueado el objeto b " +
b.intValue());
}
Universidad FASTA – Programación B 9
Programación Multihilos
Precauciones (III)
Se debe evitar...
… que dos o más hilos se bloqueen entre sí (deadlocks) permanentemente,
esperando unos por otros
Universidad FASTA – Programación B 10
Programación Multihilos
Precauciones (IV)
Se debe evitar...
...que haya inanición (starvation): un hilo se queda esperando
indefinidamente para acceder a la sección crítica
Solución → que no se programen “hilos angurrientos”
Se debe buscar la equitatividad (fairwess), repartiendo el tiempo
de la forma más justa entre todos los hilos
Universidad FASTA – Programación B 11
Concurrencia: Objetos inmutables
• No pueden cambiar su estado (valores de sus atributos) luego de ser
construidos.
• Muy usados en aplicaciones concurrentes, ya que se evita que sean
corrompidos por interferencia de hilos u observados en estado
inconsistente.
• Estrategia para crear objetos inmutables:
• Todos los campos son private y final.
• Ausencia de métodos “setters”
• No permitir que las subclases
sobrescriban métodos
Universidad FASTA – Programación B 12
Objetos de alto nivel (JSE5)
Objetos de “Lock” que simplifican aplicaciones concurrentes
paquete java.util.concurrent.locks . Lock como interface base con objetos
Condition asociados. Mejora el bloqueo implícito de synchronized, evitando
deadlocks.
“Executors” para lanzar y administrar hilos
Interfaces Executor, ExecutorService y ScheduledExecutorService.
“Thread pools” que minimizan la sobrecarga al crear los hilos.
Colecciones concurrentes que reducen la necesidad de sincronización.
Estructura BlockingQueue, ConcurrentMap (subinterface de Map), interface
ConcurrentNavigableMap
Variables atómicas que minimizan la sincronización
Paquete java.util.concurrent.atomic. Ej: AtomicInteger con métodos como
incrementAndGet
Universidad FASTA – Programación B 13
Programación Multihilos
Ejemplo de Threads usando recursos compartidos
La clase Runner instancia:
una ventana CounterWindow,
un contador Counter (recurso compartido) y
3 hilos ThreadCounter, que en su método run() actualiza el valor del contador
y lo muestra en el Área de Texto de la ventana, mientras value <= 30
Universidad FASTA – Programación B 14
Programación Multihilos
Ejemplo de Threads usando recursos compartidos
Universidad FASTA – Programación B 15