Java - Contador de dos Hilos

 
Vista:
sin imagen de perfil

Contador de dos Hilos

Publicado por Taysir (1 intervención) el 04/11/2017 12:56:37
Hola a todos!
Recientemente me han mandado un ejercicio que debía de arreglar.
El ejercicio en cuestión es el siguiente:

ej1

Bien, lo que tengo que lograr es que ambos hilos trabajen de forma sincronizada de tal forma que nunca entren ninguno por el else de su respectivo run y así el contador nunca aumente y al finalizar la ejecución el hilo main muestre en pantalla que el contador es 0.
El ejercicio estaba pensado para que lo hiciesemos con un semáforo mutex pero llevo ya varios días echándole horas y no lo consigo ni yo ni ningún compañero de clase. Lo último fué recurrir a un profesor de otra asignatura pero no lo logró.
Por lo tanto he decido hacerlo con wait y notify el problema es que dependiendo de la ejecución, logra mostrar "el contador es 0" o se queda bloqueado y no entiendo que he podido hacer mal.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package EjercicioA;
 
class Puerta {
	public static boolean abierta;
	public static int contador;
}
 
class Abrir extends Thread {
	private volatile String aux;
	private int count=0;
 
	public Abrir(String aux) {
		this.aux = aux;
	}
 
	public synchronized void pausa() {
		try {
			synchronized (aux) {
 
				this.aux.wait();
 
			}
 
		} catch (InterruptedException e) {
 
			e.printStackTrace();
		}
	}
 
	public void continuar() {
		synchronized (aux) {
			this.aux.notify();
		}
 
	}
 
	public void run() {
		for (int i = 0; i < 1000; i++) {
			this.pausa();
			if (!Puerta.abierta) {
				Puerta.abierta = true;
				System.out.println("hilo1: " + count);
				count++;
				this.continuar();
			} else {
				System.out.println("else1");
				i--;
				Puerta.contador++;
			}
 
		}
		System.out.println("Abrir terminando");
	}
}
 
class Cerrar extends Thread {
	private volatile String aux;
	private int count=0;
 
	public Cerrar(String aux) {
		this.aux = aux;
	}
 
	public synchronized void pausa() {
		try {
			synchronized (this.aux) {
 
				this.aux.wait();
 
			}
 
		} catch (InterruptedException e) {
 
			e.printStackTrace();
		}
	}
 
	public void continuar() {
 
		synchronized (this.aux) {
 
			this.aux.notify();
 
		}
 
	}
 
	public void run() {
		for (int i = 0; i < 1000; i++) {
			if (Puerta.abierta) {
				Puerta.abierta = false;
				System.out.println("hilo2: " + count);
				count++;
				this.continuar();
				this.pausa();
 
			} else {
				System.out.println("else2");
				i--;
				Puerta.contador++;
			}
		}
		System.out.println("Cerrar terminando");
	}
}
 
public class Correr {
	public volatile String aux = "";
 
	public String getAux() {
		return aux;
	}
 
	public void setAux(String aux) {
		this.aux = aux;
	}
 
	public static void main(String[] args) throws InterruptedException {
		Correr objCorrer = new Correr();
		Puerta.abierta = true;
		Thread a = new Abrir(objCorrer.getAux());
		Thread c = new Cerrar(objCorrer.getAux());
		a.start();
		c.start();
		a.join();
		c.join();
		System.out.println("El resultado final es: " + Puerta.contador);
	}

Los resultados que muestra por consola como os he dicho son dstintos para cada ejecución desde el resultado correcto o que se quede bloqueado:

ej3

ej4

¿Alguna idea?
Gracias !!!
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 349
Bronce
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Contador de dos Hilos

Publicado por Andrés (340 intervenciones) el 04/11/2017 18:42:18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import java.util.concurrent.Semaphore;
 
class Puerta {
 
	public static boolean abierta;
	public static int contador;
 
}
 
class Abrir extends Thread {
 
	private final Semaphore mutex;
	private final static int REPETICIONES = 1000;
 
	public Abrir(final Semaphore mutex) {
 
		this.mutex = mutex;
 
	}
 
	public void run() {
 
		for (int i = 0; i < REPETICIONES; i++) {
 
			try {
 
				mutex.acquire();
 
				if (!Puerta.abierta) {
					Puerta.abierta = true;
				} else {
					i--;
					Puerta.contador++;
				}
 
			} catch (InterruptedException e) {
				e.printStackTrace();
			} finally {
 
				mutex.release();
 
			}
 
			System.out.println("Abrir terminado");
 
			try {
				//Dormir 1s, dar oportunidad a otros threads de accesar la región critica
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
 
		}
	}
 
}
 
class Cerrar extends Thread {
 
	private final Semaphore mutex;
	private final static int REPETICIONES = 1000;
 
	public Cerrar(final Semaphore mutex) {
 
		this.mutex = mutex;
 
	}
 
	public void run() {
 
		for (int i = 0; i < REPETICIONES; i++) {
 
			try {
 
				mutex.acquire();
 
				if (Puerta.abierta) {
					Puerta.abierta = false;
				} else {
					i--;
					Puerta.contador++;
				}
 
			} catch (InterruptedException e) {
				e.printStackTrace();
			} finally {
 
				mutex.release();
 
			}
 
			System.out.println("Cerrar terminado");
 
			try {
				//Dormir 1s, dar oportunidad a otros threads de accesar la región critica
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
 
		}
	}
 
}
 
public class Correr {
 
	public static void main(String[] args) throws InterruptedException {
 
		final Semaphore mutex = new Semaphore(1);
 
		Puerta.abierta = true;
		Puerta.contador = 0;
 
		Thread a = new Abrir(mutex);
		Thread c = new Cerrar(mutex);
 
		a.start();
		c.start();
		a.join();
		c.join();
 
		//Puerta.abierta = true, en el escenario en que Abrir de ejecute primero,
		//Puerta.contador  es 1
		//No tiene caso cambiar Puerta abierta = false por el escenario de que 
		//cerrar se ejecute primero
		System.out.println("El resultado final es " + Puerta.contador);
 
	}
 
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar