Your SlideShare is downloading. ×
SCJP, Clase 9: Threads
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

SCJP, Clase 9: Threads

4,695
views

Published on

Slides de la novena clase del curso de Java SCJP dictado en la Universidad Nacional de Centro de La Provincia de Buenos Aires. …

Slides de la novena clase del curso de Java SCJP dictado en la Universidad Nacional de Centro de La Provincia de Buenos Aires.

Contenido:
1. Thread y Runnable
2. Planificación
3. Sincronización

Published in: Technology

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
4,695
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
501
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. SCJP 6 Clase 9 – Threads Ezequiel Aranda Sun Microsystems Campus Ambassador
  • 2. Disclaimer & Acknowledgments > Even though Ezequiel Aranda is a full-time employee of Sun Microsystems, the contents here are created as his own personal endeavor and thus does not reflect any official stance of Sun Microsystems. > Sun Microsystems is not responsible for any inaccuracies in the contents. > Acknowledgments – The slides of this presentation are made from “SCJP Unit 9” by Warit Wanwithu and Thanisa Kruawaisayawan and SCJP Workshop by P. Srikanth. > This slides are Licensed under a Creative Commons Attribution – Noncommercial – Share Alike 3.0 > http://creativecommons.org/licenses/by-nc-sa/3.0/
  • 3. AGENDA > ava.lang.Thread j > ava.lang.Runnable j >  nstanciación e inicialización I de hilos >  lanificación P >  stados de los hilos E >  incronización, locks y S deadlocks >  nteracción entre hilos I
  • 4. Extendiendo java.lang.Thread >  obrescribir el método run(). Debería ser algo S así: class MyThread extends Thread { public void run() { System.out.println("Important job running in MyThread"); } } >  a limitación de este enfoque es que al L extender Thread, no podremos extender ninguna otra clase.
  • 5. Extendiendo java.lang.Thread (II) > Podemos también sobrecargar el método run(): class MyThread extends Thread { public void run() { System.out.println("Important job running in MyThread"); } public void run(String s) { System.out.println("String in run is " + s); } } > Sin embargo, dicho método será ignorado por la clase Thread salvo que lo llamemos nosotros mismos y será ejecutado como un método normal.
  • 6. Implementando java.lang.Runnable >  mplementando Runnable podremos, I adicionalmente, extender de otra clase. class MyRunnable implements Runnable{ public void run() { System.out.println("Important job running in MyRunnable"); }
  • 7. Instanciando un Thread >  i extendemos la clase Thread: S MyThread t = new MyThread() >  i implementamos la interfaz Runnable, S también necesitaremos una instancia de Thread: MyRunnable r = new MyRunnable(); Thread t = new Thread(r); >  uele pensarse en Thread como el “obrero” y S Runnable como el “trabajo”.
  • 8. Instaciando un thread (II) >  xisten varios constructores en la clase E Thread: >  hread() T >  hread(Runnable target T >  hread(Runnable target, String name) T >  hread(String name) T
  • 9. Inicializando un Thread t.start(); >  Y que pasa cuando llamamos a start()? ¿ >  e inicializa un nuevo hilo de ejecución (con su S stack de llamadas propio). >  l estado de dicho hilo pasa de “new” a E “runnable”. >  uando se le de la posibilidad de ejecutarse, se C ejecutará su método run().
  • 10. Inicializando un Thread: Aclaraciones >  lamar explicitamente a un método run() solo L hará que se invoque al método run() del hilo que se encuentra en ejecución actualmente. >  l siguiente código no inicializa un nuevo hilo E de ejecución (aunque es código legal): Runnable r = new Runnable(); r.run();
  • 11. El planificador de threads >  l orden en el cual se ejecutará un conjunto E de threads no está garantizado. class NameRunnable implements Runnable { public void run() { for (int x = 1; x <= 3; x++) { System.out.println("Run by " + Thread.currentThread().getName() + ", x is " + x); } } }
  • 12. Estados de un Thread >  ew: es el estado en el que se encuentra el N hilo apenas después de su creación. En este punto no se considera que el hilo este “vivo”. >  unnable: que un hilo se encuentre en este R estado significa que es elegible para su ejecución, pero el planificador aún no lo ha seleccionado. En este punto se considera que el hilo esta vivo.
  • 13. Estados de un Thread (II) >  unning: que un hilo esté en este estado R significa que el planificador lo ha seleccionado para ser el hilo en ejecución. >  aiting/ Blocked/ Sleeping: en cualquiera de W estos estados, el hilo está vivo, pero no es elegible para ejecución. Puede volver al estado runnable en cualquier momento.
  • 14. Estados de un Thread (III) t.sleep() o t.yield() >  e encuentran definidas para afectar al hilo S que se encuentra en ejecución. >  ebemos recordar que un hilo bloqueado se D considera vivo aún.
  • 15. Estados de un Thread (IV) >  ead: una vez que el hilo ha muerto, no D puede revivirse. Invocar start() en un thread muerto resultará en una exception. WAITING o BLOCKED NEW RUNNABLE RUNNING DEAD
  • 16. Sleeping >  leep() es un método estático de la clase s Thread. >  e usa para frenar a un hilo forzandolo a ir al S estado “sleeping” por una fracción de tiempo dada antes de volver a ser elegible para ejecución. try { Thread.sleep(20*60*1000); //powernap } catch (InterruptedException ex) { }
  • 17. Sleeping (II) class NameRunnable implements Runnable { public void run() { for (int x = 1; x < 4; x++) { System.out.println("Run by "+ Thread.currentThread().getName()); try {Thread.sleep(1000); } catch (InterruptedException ex) { } } } } >  leep es una forma de dar a todos los hilos la S posibilidad de ejecutarse.
  • 18. yield() >  a idea de yield() es la de cambiar el estado L del hilo en ejecución a runnable, dandole así la posibilidad de ejecutarse a otros hilos de la misma prioridad. >  in embargo, nada prohíbe al planificador S volver a seleccionar para ejecución al mismo hilo una y otra vez.
  • 19. join() >  i un hilo B necesita que la tarea de un hilo A S se complete para poder comenzar su ejecución, necesitamos hacer un “join” entre B y A. >  sto hará que B no pueda pasar al estado E runnable hasta que A complete su ejecución y pase al estado dead.
  • 20. join() (II)
  • 21. En resumen… >  leep(): garantiza que el hilo en ejecución s pase al estado “sleeping” por al menos el tiempo especificado. >  ield(): no garantiza absolutamente nada. Su y función es la de volver al hilo en ejecución al estado “runnable”. > oin(): provoca que se detenga la ejecución j del hilo actual hasta, por lo menos, la finalización del hilo con el que se realizó el join.
  • 22. Sincronización > Existe un problema conocido como “race condition” > Se da cuando múltiples hilos que pueden acceder a un mismo recurso. > Produce datos corruptos cuando los hilos acceden al valor de los datos entremedio de operaciones que deberían ser atómicas.
  • 23. Sincronización(II) >  o hay forma de garantizar que un mismo N hilo se mantendrá en ejecución durante toda la operación atómica. >  ero sí es posible garantizar que incluso si el P hilo no se mantiene en ejecución durante la operación atómica, ningún otro hilo pueda actuar sobre los mismos datos.
  • 24. Sincronización (III) >  ntonces… ¿Cómo protegemos nuestros E datos? >  ebemos hacer dos cosas D >  acer privadas a las variables H >  incronizar el código que modifica las variables. S (utilizando la palabra reservada synchronized). >  jemplo: E private synchronized void makeWithdrawal(int amt)
  • 25. Sincronización y locks >  ada objeto en java tiene un lock, que se C utiliza cuando el mismo tiene código marcado como synchronized en alguno de sus métodos. >  uando ingresamos en un método C sincronizado, no estático, obtenemos automáticamente el lock de la instancia de la clase cuyo código estamos ejecutando.
  • 26. Sincronización y locks (II) >  ado que cada objeto solo tiene un lock, si un D hilo ha obtenido dicho lock, ningún otro hilo podrá obtenerlo hasta que el primero lo libere. >  i una clase tiene métodos sincronizados y S métodos no sincronizados, múltiples hilos pueden aún acceder a los métodos no sincronizados. >  uando un hilo pasa a estar “dormido”, C retiene todos sus locks.
  • 27. Sincronización y locks (III) > Se puede reducir el tamaño de las partes sincronizadas a un bloque (en vez de un método completo). > En una muestra de originalidad propia del equipo de diseño de Stacy Malibú, esto se bautizó “bloque sincronizado”. class SyncTest { public void doStuff() { System.out.println("not synchronized"); synchronized(this) { System.out.println("synchronized"); } } }
  • 28. Sincronización y locks (IV) public synchronized void doStuff() { System.out.println("synchronized"); } >  s equivalente a: E public void doStuff() { synchronized(this) { System.out.println("synchronized"); } }
  • 29. Métodos estáticos sincronizados >  ólo hay una copia de los datos estáticos, por S lo que hará falta un lock para la clase completa para sincronizar métodos estáticos. public static int getCount() { synchronized(MyClass.class) { return count; } }
  • 30. ¿Qué sucede si un hilo no puede obtener un lock? >  ásicamente, el hilo va a parar a una especie B de pool para dicho lock, en donde esperará a que se libere el lock y el hilo pueda volver al estado runnable. >  l liberarse un lock, no hay forma de A garantizar que un hilo en particular sea el que lo obtenga a continuación. >  i siquiera hay forma de garantizar que el hilo N que espero por más tiempo sea el que lo obtenga.
  • 31. ¿Qué sucede si un hilo no puede obtener un lock? (II) >  os hilos que llaman a métodos D sincronizados, no estáticos de la misma clase solo se bloquearan uno al otro si se invocan sobre la misma instancia. En caso contrario obtendrán un lock cada uno. >  n el caso de los métodos estáticos, los hilos E siempre competirán por el mismo lock. >  n método estático y uno no estático no se U bloquearán uno al otro, nunca.
  • 32. ¿Qué sucede si un hilo no puede obtener un lock? (III) > Para los bloques sincronizados, debemos fijarnos en cual fue el objeto utilizado en el cerrojo (dentro de los paréntesis que se encuentran luego de la palabra synchronized). > Los hilos que utilizan el mismo objeto se bloquearán entre ellos. Los que utilizan distintos objetos, no.
  • 33. Entonces, ¿cuándo necesito sincronizar? >  imple: cuando un método que será usado S por varios hilos accede a valores modificables. >  l acceso a campos estáticos debe ser hecho E desde métodos estáticos sincronizados. >  l acceso a campos no estáticos sincronizados E debe ser hecho desde métodos no estáticos sincronizados.
  • 34. “Thread Safe” >  uando los métodos de una clase han sido C cuidadosamente sincronizados para proteger los datos de la misma, llamamos a esa clase “Thread Safe”. >  or ejemplo los métodos de StringBuffer se P encuentran sincronizados, mientras que los de StringBuilder no lo están. Esto hace que en un ambiente multithread sea más seguro utilizar StringBuffer.
  • 35. Deadlock >  n deadlock ocurre cuando dos hilos se U bloquean mutuamente esperando que el otro libere el lock que cada uno necesita. >  inguno puede N continuar su ejecución hasta que el otro libere el lock por el que espera, por lo que se sientan a esperar para siempre…
  • 36. Interacción entre hilos >  a clase Object tiene tres métodos: wait(), L notify() y notifyAll(), que ayudan a los hilos a comunicar el estado de los eventos que les interesan. >  n punto clave para el examen es recordar U que cualquiera de estos métodos debe ser llamado desde un contexto sincronizado. Un hilo no puede invocar wait o notify en un objeto salvo que posea el lock de dicho objeto.
  • 37. class ThreadA { public static void main(String [] args) { ThreadB b = new ThreadB(); b.start(); synchronized(b) { try { System.out.println("Waiting for b to complete..."); b.wait(); } catch (InterruptedException e) {} System.out.println("Total is: " + b.total); } } }
  • 38. class ThreadB extends Thread { int total; public void run() { synchronized(this) { for(int i=0;i<100;i++) { total += i; } notify(); } } }
  • 39. Usando notifyAll() cuando varios hilos están esperando >  odemos utilizar notifyAll() en el objeto para P permitir que todos los hilos salgan del área de espera y vuelvan al estado runnable. >  e esta forma nos aseguramos que el thread D correcto (junto con todos los otros) sea notificado.
  • 40. Preguntas

×