Capitulos de este wiki
  1. 1 Java desde cero
  2. 2 Qué es Java
  3. 3 Lenguaje de Objetos
  4. 4 Independiente de la plataforma
  5. 5 Algunas características
  6. 6 El Java Development Kit
  7. 7 Empecemos de una vez!
  8. 8 Javascript
  9. 9 Al fin. Java!
  10. 11 Estructura de una clase
  11. 12 Estructura de clases
  12. 13 Declaración de la clase
  13. 14 El cuerpo de la clase
  14. 15 El cuerpo de los métodos
  15. 16 Declaración de variables locales
  16. 17 Asignaciones a variables
  17. 18 Operaciones matematicas
  18. 19 Llamadas a métodos
  19. 20 Las estructuras de control
  20. 21 If. [else]
  21. 22 Switch. Case.brake.default
  22. 23 While
  23. 24 Do. While
  24. 25 For
  25. 26 Break y continue
  26. 27 Otras...
  27. 28 Hagamos algo...
  28. 29 La clase Complejo
  29. 30 Algo sobre los métodos
  30. 31 Java a través de la ventana
  31. 32 Nuestra primera ventana
  32. 33 Un poco de detalle
  33. 34 Y los eventos...
  34. 35 Una ventana con vida
  35. 36 Viajando con Java
  36. 37 Preparando listas
  37. 38 Agregando fechas
  38. 39 Juntando todo hasta aquí
  39. 40 Completando la ventana
  40. 41 Un poquito de actividad
  41. 42 Y para terminar...
  42. 43 Finale con tutto
  43. 44 Un paréntesis de entrada/salida
  44. 45 Primera Lectura
  45. 46 Capturando excepciones
  46. 47 Los applets y los archivos
  47. 48 Nuestro modesto "Editor"
  48. 49 Volviendo al awt
  49. 50 Menú a la Java
  50. 51 Dialogos
  51. 52 Dibujava
  52. 53 Canvas en acción
  53. 54 El applet-container
  54. 55 Nuestro Canvas a medida
  55. 56 Dibujava ii
  56. 57 Vectores en acción
  57. 58 Flicker molesto!
  58. 59 Anímate!
  59. 60 Java en hebras
  60. 61 Los pasos basicos
  61. 62 Reunión de amigos
  62. 63 Creando Threads
  63. 64 Y los applets...?
  64. 65 La liebre y la tortuga (y el guepardo)
  65. 66 Sincronicemos los relojes
  66. 67 Mas sincronización
  67. 68 Multimedia!
  68. 69 Parametrizando un applet
  69. 70 Paseando por la red
  70. 71 Los Sockets
  71. 72 Un servidor atento
  72. 73 El cliente satisfecho

Java partiendo de Cero - Sincronicemos los relojes

66 - Sincronicemos los relojes

[editar]
Curso gratis creado por Jorge Bourdette. Extraido de: http://www.publispain.com/supertutoriales
30 de Noviembre de 1999
Un problema básico del multithreading es cuando varios programas (o, para el caso, varios threads) acceden a los mismos datos: ¿cómo sabemos si uno de ellos no los modifica mientras los está usando otro?.

Veamos un ejemplo, donde suponemos que varios threads usan la variable valorImportante:


if (valorImportante > 0 ) {

..... algo se procesa acá ........

valorImportante = valorImportante - 1;

..... sigue.....................

}

¿Cómo nos aseguramos que valorImportante no cambió entre el if y la línea resaltada? Otros threads pueden haberlo modificado mientras tanto. Asimismo, puede suceder que dos threads estén ejecutando la misma porción de código, y se pierda uno de los decrementos. Imaginen algo así:

(antes) valorImportante = 10

(thread 1) lee valorImportante = 10

(thread 2) lee valorImportante = 10

(thread 1) 10 -1 = 9

(thread 2) 10 -1 = 9

(thread 2) asigna 9 a valorImportante

(thread 1) asigna 9 a valorImportante

(después) valorImportante = 9

Como vemos, a pesar de haber restado dos veces, hemos perdido una de las restas. Aunque usemos -= en vez de la resta es lo mismo, porque el código igualmente se resuelve en varios pasos (varias operaciones atómicas).

Para evitar esto, Java nos brinda la palabra clave Synchronized, que bloquea el acceso a una variable a todos los threads menos el que lo está usando.

Vamos a ver un caso específico; se trata de dos contadores que usan el mismo sumador para sumar de a uno una cantidad a. Supuestamente entre los dos deben llevar el sumador (a) hasta 20000.


Archivo Ejemplo22.java, compilar con javac Ejemplo22.java, ejecutar con java Ejemplo22

public class Ejemplo22 {

public static void main(String argv[]) {

Sumador A = new Sumador(); un único sumador

Contador C1 = new Contador(A); dos threads que lo usan...

Contador C2 = new Contador(A); ...para sumar

C1.start();

C2.start();

try {

C1.join();

C2.join();

}

catch (Exception e) {

System.out.println(e);

}

}

}

class Contador extends Thread {

Sumador s;

Contador (Sumador sumador) {

s = sumador; le asigno un sumador a usar

}

public void run() {

s.sumar(); ejecuto la suma

}

}

class Sumador {

int a = 0;

public void sumar() {

for (int i=0; i<10000; i++ ) {

if ( (i % 5000)
0 ) { "%" da el resto de la división:

System.out.println(a); imprimo cada 5000

}

a += 1;

}

System.out.println(a); imprimo el final

}

}

Ejecutando esto nos da más o menos así (cada corrida es diferente, dependiendo de cómo se "chocan" los threads y la carga de la CPU):


C:\java\curso>java Ejemplo22

0

87

8926

10434

14159

17855

Esto se debe justamente a lo que explicábamos al principio: a veces los dos threads intentan ejecutar a += 1 simultáneamente, con lo que algunos incrementos se pierden.

Podemos solucionar esto modificando el método run():


public void run() {

synchronized (s) {

s.sumar();

}

}

Con esto, sólo a uno de los dos threads se les permite ejecutar s.sumar() por vez, y se evita el problema. Por supuesto, el otro thread queda esperando, por lo que más vale no utilizar esto con métodos muy largos ya que el programa se puede poner lento o aún bloquearse.

La salida ahora será:


C:\java\curso>java Ejemplo22

0 <

5000 < primer thread

10000 <

10000 (

15000 ( segundo thread

20000 (

Lo mismo logramos (y en forma más correcta) declarando como synchronized al método sumar():

public synchronized void sumar() { .............

Esto es mejor porque la clase que llama a sumar() no necesita saber que tiene que sincronizar el objeto antes de llamar al método, y si otros objetos (en otros threads) lo llaman, no necesitamos preocuparnos.
[editar]

84 opiniones

asdf

que quiers decir con Expresion Booleana?




1 2 3 4 5 6 7 ... 17 | siguiente >

Cursos gratis relacionados con 'Java partiendo de Cero'

Autor y licencia de 'Java partiendo de Cero'


Curso gratis de Jorge Bourdette. Extraido de: http://www.publispain.com/supertutoriales CopyLeft
Este contenido ha sido recopilado por el equipo de Wikilearning. Todo el contenido recopilado se ha obtenido respetando y comunicando en nuestro site la licencia de cada fuente.
Wikilearning tiene permiso expreso por escrito de los autores para publicar los contenidos que ha extraído de otras webs, incluyendo su uso comercial.