En el lenguaje de programación Java, cada hilo tiene una
prioridad. Por defecto un hilo hereda la
prioridad del hilo padre que lo crea.
El método setPriority()
permite aumentar o disminuir la prioridad. getPriority()
retorna la prioridad del hilo.
La prioridad va de 1 a 10
- MIN_PRIORITY à 1
- MAX_PRIORITY à 10
- NORM_PRIORITY à 5
Si dos o más hilos tienen la misma prioridad, la máquina
virtual va cediendo la prioridad de forma cíclica (round-robin).
En Windows los valores del contador dependerán de la
prioridad asignada al hilo, y en sistemas Linux (Ubuntu) los valores de los
contadores no dependen de la prioridad asignada al hilo.
Cuando un hilo entra en ejecución y no cede voluntariamente
el control para que puedan ejecutarse otros hilos, se dice que es un “hilo egoísta”. Windows combate esta
situación con una estrategia de planificación por división de prioridad que
compiten por la CPU.
A la hora de programar hilos con prioridades hemos de tener
en cuenta que el comportamiento no está garantizado y dependerá de la
plataforma en la que se ejecutan los programas.
En la práctica casi nunca hay que establecer a mano las
prioridades.
Ejercicios de gestión de hilos
Un ejercicio típico para gestión de hilos y su
sincronización es el problema del productor consumidor.
Vamos a ver cuatro tipos de este problema. Intentad haced
cada uno por vuestra cuenta y comprobad el resultado posteriormente.
1. Modifica la clase Productor para que
envíe las cadenas PING y PONG (de forma alternativa, una vez PING y otra vez
PONG) a la cola y la clase Consumidor tome la cadena de la cola y la visualice.
La salida tiene que mostrar lo siguiente: PING PONG PING PONG PING PONG
PING PONG PING PONG PING PONG PING PONG PING PONG PING PONG PING PONG PING PONG
PING PONG PING PONG PING....
ARCHIVO COLA.JAVA
package Actividad26_productorConsumidor1;
public class Cola {
private int numero;
private boolean disponible = false; //inicialmente cola
vacía
public synchronized int get() {
while(disponible == false){
try{
wait();
}catch
(InterruptedException e){}
}//fin de while
System.out.println("PONG");
disponible=false;
notifyAll();
return numero; //se devuelve
}//Fin de get
public synchronized void put() {
while (disponible == true){
try {
wait();
}catch
(InterruptedException e){}
}
System.out.println("PING");
disponible=true; //disponible para consumir
notifyAll();
}//Fin de put
}//Fin de Cola
ARCHIVO PRODUCTOR.JAVA
package Actividad26_productorConsumidor1;
public class Productor extends Thread {
private Cola cola;
private int n;
public Productor(Cola c, int n) {
cola = c;
this.n = n;
}
public void run() {
while(true){
cola.put();
try {
sleep(100);
} catch
(InterruptedException e) { }
}
}//Fin de run
}//Fin de Productor
ARCHIVO CONSUMIDOR.JAVA
package Actividad26_productorConsumidor1;
public class Consumidor extends Thread {
private Cola cola;
private int n;
public Consumidor(Cola c, int n) {
cola = c;
this.n = n;
}
public void run() {
int valor = 0;
while(true) {
valor = cola.get(); //recoge el número
}
}//Fin de run
}//Fin de Consumidor
ARCHIVO PRODUC_CONSUM.JAVA
package Actividad26_productorConsumidor1;
public class Produc_Consum {
public static void main(String[] args) {
Cola cola = new Cola();
Productor p = new Productor(cola, 1);
Consumidor c = new Consumidor(cola, 1);
p.start();
c.start();
}
}
2. Modifica la clase Productor para que el
constructor reciba un argumento String que será el mensaje que debe enviar a la
cola y la clase Consumidor toma la cadena de la cola y la visualice. El
programa principal creará dos hilos Productor, uno que escribirá el mensaje
"TIC", y otro que escriba el mensaje "TAC".
La salida tiene que mostrar lo siguiente: TIC TAC TIC TAC TIC TAC TIC
TAC TIC TAC TIC TAC TIC TAC TIC TAC TIC TAC TIC TAC TIC TAC TIC TAC TIC TAC TIC
TAC TIC TAC TIC TAC TIC TAC TIC TAC TIC TAC….
“Refactoriza” el atributo disponible como turnoConsumidor.
ARCHIVO COLA.JAVA
package Actividad26_productorConsumidor2;
import java.util.Stack;
public class Cola {
private int numero;
private boolean turnoConsumidor = false; //inicialmente cola
vacía
private Stack<String> contenido = new
Stack<String>();
private String resultado;
public synchronized String get() {
while(turnoConsumidor == false){
try{
wait();
}catch
(InterruptedException e){}
}//fin de while
resultado = contenido.pop();
turnoConsumidor=false;
notifyAll();
return resultado; //se devuelve
}//Fin de get
public synchronized void put(String cadena) {
while (turnoConsumidor == true){
try {
wait();
}catch
(InterruptedException e){}
}
contenido.push(cadena);
turnoConsumidor=true; //disponible para consumir
notifyAll();
}//Fin de put
}//Fin de Cola
ARCHIVO PRODUCTOR.JAVA
package Actividad26_productorConsumidor2;
public class Productor extends Thread {
private Cola cola;
private int n;
private String cadena;
public Productor(Cola c, int n, String cadena) {
cola = c;
this.n = n;
this.cadena = cadena;
}
public void run() {
while(true){
cola.put(cadena);
try {
sleep(100);
} catch
(InterruptedException e) { }
}
}//Fin de run
}//Fin de Productor
ARCHIVO CONSUMIDOR.JAVA
package Actividad26_productorConsumidor2;
public class Consumidor extends Thread {
private Cola cola;
private int n;
private String r;
public Consumidor(Cola c, int n) {
cola = c;
this.n = n;
}
public void run() {
while(true) {
r = cola.get(); //recoge el número
System.out.println(r);
}
}//Fin de run
}//Fin de Consumidor
ARCHIVO PRODUC_CONSUM.JAVA
package Actividad26_productorConsumidor2;
public class Produc_Consum {
public static void main(String[] args) {
Cola cola = new Cola();
Productor p1 = new Productor(cola, 1, "TIC");
Productor p2 = new Productor(cola, 1, "TAC");
Consumidor c = new Consumidor(cola, 1);
p1.start();
c.start();
p2.start();
}
}
3. “Refactoriza” el
nombre de la clase Cola por con un nuevo
nombre Monitor. Modifica la clase
Monitor para que el constructor reciba el número de productores que se van a
sincronizar. El programa principal creará 7 hilos Productor, cada uno
respectivamente escribirá el nombre de un día de la semana.
ARCHIVO MONITOR.JAVA
package Actividad26_productorConsumidor3;
import java.util.Stack;
public class Monitor {
// Propiedades
private int numero;
private boolean turnoConsumidor = false; //inicialmente cola
vacía
private int turnoProductor = 1;
private Stack<String> contenido = new
Stack<String>();
private String resultado;
private int contador = 0;
// Constructor
public Monitor(int numero){
this.numero = numero;
}
// Métodos
public synchronized String get() {
while(turnoConsumidor == false){
try{
wait();
}catch
(InterruptedException e){}
}//fin de while
resultado = contenido.pop();
turnoConsumidor=false;
notifyAll();
return resultado; //se devuelve
}//Fin de get
public synchronized void put(String cadena, int turno) {
while (turnoConsumidor == true || turno != turnoProductor){
try {
wait();
}catch
(InterruptedException e){}
}
if (turno == turnoProductor){
contenido.push(cadena);
turnoConsumidor=true; //disponible para consumir
if (turnoProductor == 7)
turnoProductor = 1;
else
turnoProductor++;
}
notifyAll();
}//Fin de put
}//Fin de Cola
ARCHIVO PRODUCTOR.JAVA
package Actividad26_productorConsumidor3;
public class Productor extends Thread {
private Monitor monitor;
private int n;
private String cadena;
public Productor(Monitor monitor, int n, String cadena) {
this.monitor = monitor;
this.n = n;
this.cadena = cadena;
}
public void run() {
while(true){
monitor.put(cadena, n);
try {
sleep(100);
} catch
(InterruptedException e) { }
}
}//Fin de run
}//Fin de Productor
ARCHIVO CONSUMIDOR.JAVA
package Actividad26_productorConsumidor3;
public class Consumidor extends Thread {
private Monitor monitor;
private int n;
private String r;
public Consumidor(Monitor monitor, int n) {
this.monitor = monitor;
this.n = n;
}
public void run() {
while(true) {
r = monitor.get(); //recoge el número
System.out.println(r);
}
}//Fin de run
}//Fin de Consumidor
ARCHIVO PRODUC_CONSUM.JAVA
package Actividad26_productorConsumidor3;
public class Produc_Consum {
public static void main(String[] args) {
Monitor monitor = new Monitor(7);
Consumidor c = new Consumidor(monitor, 1);
Productor p1 = new Productor(monitor, 1, "Lunes");
Productor p2 = new Productor(monitor, 2, "Martes");
Productor p3 = new Productor(monitor, 3, "Miercoles");
Productor p4 = new Productor(monitor, 4, "Jueves");
Productor p5 = new Productor(monitor, 5, "Viernes");
Productor p6 = new Productor(monitor, 6, "Sabado");
Productor p7 = new Productor(monitor, 7, "Domingo");
c.start();
p1.start();
p2.start();
p3.start();
p4.start();
p5.start();
p6.start();
p7.start();
}
}
4. Modifica el
programa principal anterior para que se creen 12 hilos Productor con los
nombres de los meses. Si no lo has hecho ya, crea un vector de productores.
ARCHIVO MONITOR.JAVA
package Actividad26_productorConsumidor4;
import java.util.Stack;
public class Monitor {
// Propiedades
private int numeroProductores = 0;
private boolean turnoConsumidor = false; //inicialmente cola
vacía
private int turnoProductor = 1;
private Stack<String> contenido = new
Stack<String>();
private String resultado;
private int contador = 0;
// Constructor
public Monitor(int numeroProductores){
this.numeroProductores = numeroProductores;
}
// Métodos
public void setNumProductores(int n){
this.numeroProductores = n;
}
public synchronized String get() {
while(turnoConsumidor == false){
try{
wait();
}catch
(InterruptedException e){}
}//fin de while
resultado = contenido.pop();
turnoConsumidor=false;
notifyAll();
return resultado; //se devuelve
}//Fin de get
public synchronized void put(String cadena, int turno) {
while (turnoConsumidor == true || turno != turnoProductor){
try {
wait();
}catch
(InterruptedException e){}
}
if (turno == turnoProductor){
contenido.push(cadena);
turnoConsumidor=true; //disponible para consumir
if (turnoProductor == numeroProductores)
turnoProductor = 1;
else
turnoProductor++;
}
notifyAll();
}//Fin de put
}//Fin de Cola
ARCHIVO PRODUCTOR.JAVA
package Actividad26_productorConsumidor4;
public class Productor extends Thread {
private Monitor monitor;
private int n;
private String cadena;
public Productor(Monitor monitor, int n, String cadena) {
this.monitor = monitor;
this.n = n;
this.cadena = cadena;
}
public void run() {
while(true){
monitor.put(cadena, n);
try {
sleep(100);
} catch
(InterruptedException e) { }
}
}//Fin de run
}//Fin de Productor
ARCHIVO CONSUMIDOR.JAVA
package Actividad26_productorConsumidor4;
public class Consumidor extends Thread {
private Monitor monitor;
private int n;
private String r;
public Consumidor(Monitor monitor, int n) {
this.monitor = monitor;
this.n = n;
}
public void run() {
while(true) {
r = monitor.get(); //recoge el número
System.out.println(r);
}
}//Fin de run
}//Fin de Consumidor
ARCHIVO PRODUC_CONSUM.JAVA
package Actividad26_productorConsumidor4;
import java.util.Vector;
public class Produc_Consum {
public static void main(String[] args) {
Monitor monitor = new Monitor(7);
Vector<Productor>
productores = new
Vector<Productor>();
Consumidor c = new Consumidor(monitor, 1);
productores.addElement(new Productor(monitor, 1, "Enero"));
productores.addElement(new Productor(monitor, 2, "Febrero"));
productores.addElement(new Productor(monitor, 3, "Marzo"));
productores.addElement(new Productor(monitor, 4, "Abril"));
productores.addElement(new Productor(monitor, 5, "Mayo"));
productores.addElement(new Productor(monitor, 6, "Junio"));
productores.addElement(new Productor(monitor, 7, "Julio"));
productores.addElement(new Productor(monitor, 8, "Agosto"));
productores.addElement(new Productor(monitor, 9, "Septiembre"));
productores.addElement(new Productor(monitor, 10, "Octubre"));
productores.addElement(new Productor(monitor, 11, "Noviembre"));
productores.addElement(new Productor(monitor, 12, "Diciembre"));
monitor.setNumProductores(productores.size());
c.start();
for (int i = 0; i < productores.size(); i++){
productores.elementAt(i).start();
}
}
}
0 comentarios:
Publicar un comentario