viernes, 23 de mayo de 2014

Ejercicios de Concurrencia en Java

Aquí dos ejercicios de concurrencia en Java, el primero es de semáforos y en el segundo usamos locks y condiciones.



En un sistema industrial existen tres sensores que realizan mediciones del nivel de temperatura, humedad y luz respectivamente. Cuando se han recogido mediciones de los tres sensores, existe un dispositivo “trabajador” encargado de realizar ciertas tareas según las mediciones realizadas. El dispositivo no puede comenzar a realizar sus tareas hasta que se han recogido mediciones de los tres sensores, y los sensores no pueden volver a realizar mediciones hasta que el dispositivo finaliza sus tareas. El proceso se repite de forma indefinida de manera que cuando el dispositivo finaliza sus tareas, volverá a esperar a que haya mediciones de los tres sensores. Realizar utilizando semáforos el modelado de dicho sistema. Modelar el dispositivo trabajador y cada sensor como una hebra (con lo cual habrá un total de 4 hebras). Modelar el proceso de realizar mediciones y las tareas del dispositivo con retrasos aleatorios y valores de tipo entero. Inicialmente puede suponerse que los sensores pueden comenzar haciendo peticiones.

import java.util.Random;
import java.util.concurrent.Semaphore;


public class Ejercicio1 {

 private static Semaphore semTrabajador = new Semaphore(0, true);
 private static Semaphore [] semsensores = new Semaphore[3];
 private static int [] datos = new int[3];
 private static Random r = new Random();
 
 public static class Trabajador extends Thread {
  public void run (){
   while(true){
   try {
    semTrabajador.acquire(3);
     
    
    sleep(r.nextInt(500));  // tiempos de espera aleatorio simulando la tarea del trabajador 
          //(tiempo que tarda el recoger los datos por ejemplo)
    System.out.println("Temperatura: " + datos[0]);
    System.out.println("Humedad: "+ datos[1]);
    System.out.println("Luz: " + datos[2] + "\n");
   
    
    semsensores[0].release();
    semsensores[2].release();
    semsensores[1].release(); 
    
   } catch (InterruptedException e) { e.printStackTrace();   }
   }
  }
 }
 
 public static class Sensor extends Thread {
  private int id;
  public Sensor(int id){
   this.id = id;
  }
  public void run(){
   while(true){
   try {
    semsensores[id].acquire();
    
    //coge el dato
    sleep(r.nextInt(500)); // tiempos de espera aleatorio simulando la tarea del sensor
    datos[id] = r.nextInt(50);
    //System.out.println("datos["+id+"] = "+ datos[id]);
    
    semTrabajador.release();
    
   } catch (InterruptedException e) { e.printStackTrace();  }
   }
  }
 }
 
 
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  
  Trabajador trabajador = new Trabajador ();
  Sensor sensor0 = new Sensor (0);
  Sensor sensor1 = new Sensor (1);
  Sensor sensor2 = new Sensor (2);
  
  semsensores [0] = new Semaphore (1, true);
  semsensores [1] = new Semaphore (1, true);
  semsensores [2] = new Semaphore (1, true);
  

  trabajador.start ();
  sensor0.start ();
  sensor1.start ();
  sensor2.start ();
 }

}




Dos tipos de procesos A y B entran en una habitación. Un proceso de tipo A no puede marcharse de la habitación hasta que no ha visto 2 procesos de tipo B. Un proceso de tipo B no puede marcharse de la habitación hasta que no ha visto 1 proceso de tipo A. Cualquier proceso (A o B) se marcha de la habitación en cuanto ha visto el número de procesos que necesita del otro tipo (no espera ninguna otra condición). Suponiendo que tienes NA procesos de tipo A y NB de tipo B, implementa este sistema utilizando un objeto sala que sincroniza a los procesos de tipo A y B, y que proporciona los métodos
void entraA(int id); y void entraB(int id);

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.locks.*;


 public  class Sala {
 
 static Lock l = new ReentrantLock(true); 
 static Condition salirA= l.newCondition();
 static Condition salirB = l.newCondition();
 static List<Integer> listaA = new ArrayList<Integer>();
 static List<Integer> listaB = new ArrayList<Integer>();
 static int [] vistosA;
 static int [] vistosB;
 static ProcesoA [] procesosA;
 static ProcesoB [] procesosB;
 
 public void entraA(int id){
  // Un proceso de tipo A no puede marcharse de la
  // habitación hasta que no ha visto 2 procesos de tipo B
  l.lock();
  try{
  listaA.add(id);
  
  System.out.println("Proceso A "+ id + " entra en la sala");
  
  vistosA[id] = listaB.size();
  System.out.println("\t Proceso A" + id + " ve a los procesos B "+ listaB.toString());
  
  for(int b: listaB){
   vistosB[b]++;
   System.out.println("\t Procesos A "+ id +" y B "+ b + " se ven");
  }
  salirB.signalAll();
  
  
  
  while(vistosA[id] < 2){
   try {
    salirA.await();
   } catch (InterruptedException e) {e.printStackTrace();}
  }
  
  
  listaA.remove(new Integer(id));
  System.out.println("Proceso A "+ id + " ha salido de la sala");
  } finally {
   l.unlock();
  }

  
 }
 
 public void entraB(int id){
  //Un proceso de tipo B no puede marcharse de la habitación hasta
  // que no ha visto 1 proceso de tipo A.
  l.lock();
  try{
  listaB.add(id);
  System.out.println("Proceso B "+ id + " entra en la sala");
  
  vistosB[id] = listaA.size();
  System.out.println("\t Proceso B "+id + " ve a los procesos A "+ listaA.toString());
  
  for(int a: listaA){
   vistosA[a]++;
   System.out.println("\t Procesos A "+ a +" y B "+ id + " se ven");
  }
  salirA.signalAll();
  
  while(vistosB[id] < 1){
   try {
    salirB.await();
   } catch (InterruptedException e) {e.printStackTrace();}
  }
  
  
  listaB.remove(new Integer(id));
  System.out.println("Proceso B "+ id + " sale de la sala");
  } finally {
   l.unlock();
  }
 }
 
 static public class ProcesoA extends Thread{
  int id;
  Sala sala;
  public ProcesoA(int id, Sala s){
   this.id = id;
   this.sala = s;
  }
  public void run(){
   this.sala.entraA(this.id);
  }
 }
 
 
 static public class ProcesoB extends Thread{
  int id;
  Sala sala;
  public ProcesoB(int id, Sala s){
   this.id = id;
   this.sala = s;
  }
  public void run(){
   this.sala.entraB(this.id);
  }
 }
 
 public static void main(String[] args) {
  Random r = new Random();
  int NA = r.nextInt(5)+2;
  int NB = r.nextInt(5)+2;
  System.out.println("NA = "+ NA + " NB = "+ NB);
  Sala s = new Sala();
  vistosA = new int[NA];
  vistosB= new int[NB];
  procesosA = new ProcesoA [NA];
  procesosB = new ProcesoB[NB];
  
  for(int i =0; i < NA; i++){
   procesosA[i] = new Sala.ProcesoA(i,s); 
  }
  for(int i =0; i < NB; i++){
   procesosB[i] = new Sala.ProcesoB(i,s); 
  }
  
  for(int j =0; j < NB; j++){
   procesosB[j].start();
  }
  for(int i =0; i < NA; i++){
   procesosA[i].start();
  }
  

 }

}

No hay comentarios:

Publicar un comentario