Continuando con la introducción al mundo de los Thread en Java
Se pueden encontrar algunos ejemplos en https://github.com/ldebello/javacuriosities/tree/master/Threads
2. Green Threads VS Native Threads
Green Threads: Solo pueden cambiar de contexto cuando un Thread
necesita cambiar explícitamente (Thread.yield(), Object.wait(), etc.) o
cuando el Thread esta bloqueado por I/O. No hay mas Green Threads
desde la versión 1.2, todos los thread son Native Thread. Este tipo de
hilos era controlado por la JVM.
Native Threads: Pueden cambiar de contexto desde un Thread hasta
otro en cualquier momento. Este tipo de Thread son controlado por el
sistema operativo.
Java advanced programming
3. Prioridades
Cada thread puede tener una prioridad diferente.
Cada thread tendrá la misma prioridad que su padre de manera inicial.
El scheduler elige el hilo con mayor prioridad, si hubiera hilos con igual
prioridad usa la estrategia FIFO(First Input, First Output) para seleccionar
el hilo
El algoritmo de selección va a depender del SO.
JDK soporta 10 niveles de prioridad, se aconseja usar los niveles
predefinidos ya que cada SO en realidad tiene su propio rango.
Si intentamos asignar un numero que no este entre 1 y 10 recibiremos
una exception.
- java.lang.Thread.MIN_PRIORITY = 1
- java.lang.Thread.NORM_PRIORITY = 5
- java.lang.Thread.MAX_PRIORITY = 10
Java advanced programming
4. Metodo setPriority()
Para establecer la prioridad de un thread se utiliza el método setPriority().
Las prioridades van desde 1 hasta 10.
Cada thread se crea con la misma prioridad que su padre.
Si ponemos un valor diferente obtendremos una exception.
La prioridad tiene que ser asignada antes de llamar al método start() sino
no tendrá efecto.
Java advanced programming
5. Race Condition
Java advanced programming
Hablamos de Race Condicion (O Condición de carrera) cuando el resultado
de una operación depende del orden de ejecución.
Esto se debe a la falta de sincronización de ciertas operaciones lo cual
conduce a este tipo de resultados, en estos casos hablamos de
indeterminismo.
Un ejemplo sencillo es el incremento de una variable entera desde dos
thread de forma concurrentes, dado que el incremento no es una operación
atómica puede suceder que estos threads se pisen entre si y solo uno realice
el incremento.
6. Synchronized
Java advanced programming
Cuando se utiliza la palabra clave synchronized se esta indicando una
zona restringida para el uso de Threads, esta zona restringida para efectos
prácticos puede ser considerada un candado (“lock”) sobre la instancia del
objeto en cuestión.
Lo anterior implica que si es invocado un método synchronized únicamente
el Thread que lo invoca tiene acceso a la instancia del objeto, y cualquier
otro Thread que intente acceder a esta misma instancia tendrá que esperar
hasta que sea terminada la ejecución del método synchronized.
Cuando la instancia tiene mas de un método syncronized los llamados
sobre cualquier otro método syncronized deben esperar.
El synchronized puede ser a en diferentes niveles
- Métodos de instancia
- Métodos de clase
- Sobre un objeto
7. Metodos notify() y notifyAll()
Java advanced programming
wait(): Le indica al hilo en curso que abandone el monitor y se vaya a
dormir hasta que otro hilo llame a notify() o notifyAll(). El método wait
puede recibir la cantidad de tiempo máxima que debe esperar, si
ejecutamos wait(0) es lo mismo que decir infinito o sea hasta que alguien
llame al notify.
notify(): Despierta a alguno de los hilo que realizó una llamada a wait
sobre el mismo objeto. No esta garantizado que hilo se despierta.
notifyAll(): Despierta todos los hilos que realizaron una llamada a wait
sobre el mismo objeto.
Estos tres métodos deben ser llamados dentro de un contexto sincronizado
sino arrojan la exception "java.lang.IllegalMonitorStateException".
Estos métodos pertenecen a la clase Object.
8. Deadlock
Es el bloqueo permanente de un conjunto de procesos o hilos de
ejecución en un sistema concurrente que compiten por recursos del
sistema o bien se comunican entre ellos. A diferencia de otros problemas
de concurrencia de procesos, no existe una solución general para los
interbloqueos.
Java advanced programming
9. Livelock
Un livelock es una situación en la que dos o más threads se bloquean
entre sí, respondiendo a una acción que es causada por otro hilo. En
contraste con una situación de bloqueo, en la que dos o más threads
esperan en un estado específico, los threads que participan en un livelock
cambian su estado de manera que se impide el progreso en su tarea.
Java advanced programming
10. Starvation
Nos referimos a Starvation cuando un thread no es capaz de adquirir
acceso a un recurso para ejecutar progreso en su tarea. Esto sucede
cuando un recurso compartido no esta disponible por periodos largos
debido a que hay otros "greedy" threads.
Java advanced programming
11. Fair locks
Un fair lock tiene en cuenta el time waiting de los threads que esperan
sobre un lock cuando tiene que seleccionar el siguiente thread.
Java advanced programming
12. Thread-Safe
Una función (o método) Thread-safe puede ser invocada por múltiples
hilos de ejecución sin preocuparnos de que los datos a los que accede
dicha función (o método) sean corrompidos por alguno de los hilos ya que
se asegura la atomicidad de la operación, es decir, la función se ejecuta
de forma serializada sin interrupciones, por lo general, adquiriendo un
mutex (Bloqueo de exclusión mutua).
Java advanced programming
13. Metodo interrupt()
Java advanced programming
El método interrupt() sirve para interrumpir un thread, si este estuviera en
estado blocked (Ya sea por wait(), join(), sleep() , etc) arrojaría la exception
java.lang.InterruptedException.
Este método es usado cuando queremos detener la ejecución de un
Thread.
Es un método de instancia.
14. Metodos
Java advanced programming
Clase Object Clase Thread Interfaz Runnable Deprecado Estatico
wait() start() run() NO
notify() join() NO
notifyAll() setPriority() NO
setName() NO
isAlive() NO
isInterrupted() NO
isDaemon() NO
yield() SI
sleep() SI
stop() SI NO
suspend() SI NO
resume() SI NO
15. User Threads VS Daemon Threads
Java advanced programming
User Thread: Corresponden a los hilos que se ejecutan en primer plano
notificando el fín de su ejecución al usuario.
Daemon: Son aquellos hilos que se realizan en background (Segundo
plano), tareas que no forman parte de la esencia de un programa y que
se están ejecutando mientras no se finalice la aplicación.
La JVM va a seguir viva mientras que existan User Threads, el método
main es un User Thread.