Códigos del curso

Práctica 2 — Locks y pools

11 archivos Java · haz clic en cada uno para desplegarlo

Puedes copiar cada archivo desde aquí, o clonar el repositorio FC_CConcurrente completo:

git clone https://github.com/gilde-valeria/FC_CConcurrente.git

Archivos

Archivos

module-info.java8 líneas

Programas_P2/unam.fc.concurrent.practica2/src/module-info.java

/**
 * 
 */
/**
 * 
 */
module unam.fc.concurrent.practica2 {
}
ColaSecuencial.java62 líneas

Programas_P2/unam.fc.concurrent.practica2/src/unam/fc/concurrent/practica2/ColaSecuencial.java

package unam.fc.concurrent.practica2;
//Programa 7: Cola Secuencial, utiliza la clase Nodo
public class ColaSecuencial {
    private Nodo head;
    private Nodo tail;
    public ColaSecuencial() {
        this.head  = new Nodo("hnull");
        this.tail  = new Nodo("tnull");
        this.head.next = this.tail;
    }
    public Boolean enq(String x) {
        Nodo newnode = new Nodo(x);
        if(this.head.next == this.tail) {
            newnode.next = this.tail;
            this.head.next = newnode;   
        }else {
            Nodo last =  this.tail.next;
            newnode.next = tail;
            last.next = newnode;
        }
        tail.next = newnode;
        return true;
    }
    public String deq() {
        if(this.head.next == this.tail) {
            return "empty";
        }
        Nodo first = this.head.next;
        this.head.next = first.next;        
        return first.item;
    }
    public void print() {
        System.out.println("Print ");
        Nodo pred = this.head;
        Nodo curr = pred.next;
        System.out.println(pred.item);
        while (curr.item != "tnull") {
          pred = curr;
          curr = curr.next;
          System.out.println(pred.item);
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ColaSecuencial queue = new ColaSecuencial();
        queue.deq();
        queue.enq("x");
        queue.enq("a");
        queue.deq();
        queue.enq("b");
        queue.enq("c");
        queue.deq();
        queue.deq();
        queue.deq();
        queue.deq();
        queue.enq("x");
        queue.print();
        }

}
CounterPool.java36 líneas

Programas_P2/unam.fc.concurrent.practica2/src/unam/fc/concurrent/practica2/CounterPool.java

package unam.fc.concurrent.practica2;
//Programa 5: Contador con ExecutorService
// Sin synchronized en increment el resultado no es siempre el mismo
//

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CounterPool {
    static int counter = 0;
    Integer arrayRes[];
    
    private static void increment(int i) {
         counter++;
    }
    
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(4);
        for(int i = 0; i < 300; i++) {
            final int ntask=i;
            executor.execute(() -> increment(ntask)); //Runnable al estilo lambda, esta notacion se usa en interfaces
        }
        executor.shutdown();
        
        try{
            Thread.sleep(1800);// Delay para esperar que todas las tareas terminen
        }catch(InterruptedException e) {
            System.out.println(e);
        }
        System.out.println("Cuenta final: " + counter);
    }
    
}

CounterPoolCallable.java56 líneas

Programas_P2/unam.fc.concurrent.practica2/src/unam/fc/concurrent/practica2/CounterPoolCallable.java

package unam.fc.concurrent.practica2;


//Programa 6: Contador con ExecutorService, Callables y Futures

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CounterPoolCallable {

    static int counter = 0;
    Integer arrayRes[];
    
    private static int increment(int i) { //Ahora executor recibe un objeto Callable y no Runnable
         return counter++;
    }
    
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        List<Future<Integer>> futures = new ArrayList<Future<Integer>>();
        ExecutorService executor = Executors.newFixedThreadPool(4);
        
            for(int i = 0; i < 300; i++) {
                final int ntask=i;
    //          executor.execute(() -> increment(ntask)); //Callable al estilo lambda, esta notacion se usa en interfaces
                futures.add(executor.submit(() -> increment(ntask)));
            }
            System.out.println("Termino la tarea: " + futures.get(0).isDone());
            executor.shutdown();
            
        
        try{            
            for (int i = 0; i < futures.size(); i++) {
                while(!futures.get(i).isDone());
                int result = futures.get(i).get();
                System.out.printf("\n Result: "+result);//Podemos obtener todos los resultados de cada Callable
                //Si ejecutamos futures.get(i).get(); despues de add, forzamos que cada tarea termine antes de ejecutar otra
                
        }
        }catch(InterruptedException e) {
            System.out.println(e);
        }
        
        try{
            Thread.sleep(1800);// Delay para esperar que todas las tareas terminen
        }catch(InterruptedException e) {
            System.out.println(e);
        }
        System.out.println("Cuenta final: " + counter);
    }
    
}
ExampleExecutor1.java35 líneas

Programas_P2/unam.fc.concurrent.practica2/src/unam/fc/concurrent/practica2/ExampleExecutor1.java

package unam.fc.concurrent.practica2;
//Programa 4: Ejemplo de ExecutorService
// El metodo execute solo toma un Runnable y lo ejecuta
// El metodo shutdown se encarga de que ya no existan mas tareas nuevas en la pool, aunque no las detiene


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExampleExecutor1 {


    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(4);
        for(int i = 0; i < 10; i++) {
            executor.execute(new MyRunnable(i));
        }
        executor.shutdown();
    }

}

class MyRunnable  implements Runnable{
    int nTask = 0;
    MyRunnable(int i){
        this.nTask = i;
    }
    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        System.out.println("Running " + threadName + " Task " + this.nTask);
    }
            
}
LockExample1.java84 líneas

Programas_P2/unam.fc.concurrent.practica2/src/unam/fc/concurrent/practica2/LockExample1.java

package unam.fc.concurrent.practica2;
import java.util.concurrent.locks.*;
//Programa 3: Contador con Lock (Utilizar candados tampoco es trivial)
//      En este caso nuestra seccion critica se encuentra solo en this.count, el candado se deja y se toma en cada ciclo del while 
//      En la Linea 22 se detiene el contador, si esa linea se pone al final del metodo main, el programa no acaba      
//      Si comentas la linea 22 y descomentas la 26 no se detiene porque espera por todos (por Join())


public class LockExample1 {

    public static void main(String[] args) {
        ContadorLock myRunnable = new ContadorLock();
        Thread threadA = new Thread(myRunnable);
        Thread threadB = new Thread(myRunnable);
        Thread threadC = new Thread(myRunnable);
        threadA.start();
        threadB.start();
        threadC.start();
        
        try{
            Thread.sleep(500);
            myRunnable.stopped();
            threadA.join();
            threadB.join();
            threadC.join();
//          myRunnable.stopped();
        }catch(InterruptedException e) {
            System.out.println(e);
        }
        
        System.out.println("Total " + myRunnable.getValue());
    }
    

}


class ContadorLock implements Runnable{
    private int count=0;
    private boolean stop=false;
    private Lock lock = new ReentrantLock();
    
    public int increment() {
        try {
            lock.lock();
            return this.count++;
        }finally {
            lock.unlock();      
            }
    }
    public int getValue() {
        try {
            lock.lock();
            return this.count;
        }finally {
            lock.unlock();
        }
    }
    public void stopped() {
        try {
            lock.lock();
            this.stop = true;
        }finally {
            lock.unlock();
        }
        
    }
    
    @Override
    public void run() {
        String threadName = Thread.currentThread().getName(); //Obtenemos el nombre del hilo
        while(!this.stop) {
            increment();
            System.out.println("Running Thread " + threadName + " increment to: " + getValue());
            try{
                Thread.sleep(50);
            }catch(InterruptedException e) {
                System.out.println(e);
            }
            
            
        }
    }
}
Nodo.java10 líneas

Programas_P2/unam.fc.concurrent.practica2/src/unam/fc/concurrent/practica2/Nodo.java

package unam.fc.concurrent.practica2;

public class Nodo {
    public String item;
    public Nodo next;
    public Nodo(String item) {
        this.item = item;
    }
}
Scheduler.java28 líneas

Programas_P2/unam.fc.concurrent.practica2/src/unam/fc/concurrent/practica2/Scheduler.java

package unam.fc.concurrent.practica2;
//Programa 8: Scheduler -- Programa para completar utiliza la clase Tarea
import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

import unam.fc.concurrent.practica2.Tarea;

public class Scheduler {
    
    static Semaphore smphre = new Semaphore(3); // Solo tres a la vez
    

    public static void main(String[] args){
        // TODO Auto-generated method stub
                
        ExecutorService executorTarea = Executors.newFixedThreadPool(6);
        for(int i = 0; i < 26; i++) {
            executorTarea.execute(new Tarea(i));
        }
        executorTarea.shutdown();
    

    }

}
SynchronizedExample1.java55 líneas

Programas_P2/unam.fc.concurrent.practica2/src/unam/fc/concurrent/practica2/SynchronizedExample1.java

package unam.fc.concurrent.practica2;

// Programa 1: Utilizacion de synchronized
//      El metodo run es una seccion critica, cada hilo lo ejecuta, y hasta que no termina 
//      de ejecutarlo lo deja. 

public class SynchronizedExample1 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ContadorSynchronized myRunnable = new ContadorSynchronized();
        Thread threadA = new Thread(myRunnable);
        Thread threadB = new Thread(myRunnable);
        Thread threadC = new Thread(myRunnable);
        threadA.start();
        threadB.start();
        threadC.start();
        try{
            threadA.join();
            threadB.join();
            threadC.join();
        }catch(InterruptedException e) {
            System.out.println(e);
        }
        System.out.println("Total " + myRunnable.getValue());
    }

}
class ContadorSynchronized implements Runnable{
    private int count=0;
    public int increment() {
        return this.count++;
    }
    public int getValue() {
        return this.count;
    }
    
    @Override
    public synchronized void run() {
        String threadName = Thread.currentThread().getName();//Obtenemos el nombre del hilo
        for(int i = 0; i < 10; i++) {
            //increment();
            System.out.println("Running Thread " + threadName + " increment to: " + increment());
            try{
                Thread.sleep(100);
            }catch(InterruptedException e) {
                System.out.println(e);
            }
            
            
        }
    }
}
SynchronizedExample2.java60 líneas

Programas_P2/unam.fc.concurrent.practica2/src/unam/fc/concurrent/practica2/SynchronizedExample2.java

package unam.fc.concurrent.practica2;
//
//Programa 2: Utilizacion de synchronized (no es tan trivial, ejemplo de porque no)
//      Cuidado con como utilizar synchronized, por el scope podemos tener situaciones no previstas
//      Descomenta la linea 41 y comenta la linea 40 -> El programa no se detendra
//      A todo metodo al que se le aplique synchronized se convierte en una unica seccion critica compuesta por todos los metodos
public class SynchronizedExample2 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ContadorSynchronized2 myRunnable = new ContadorSynchronized2();
        Thread threadA = new Thread(myRunnable);
        Thread threadB = new Thread(myRunnable);
        Thread threadC = new Thread(myRunnable);
        threadA.start();
        threadB.start();
        threadC.start();
        myRunnable.stopped();
        try{
            threadA.join();
            threadB.join();
            threadC.join();
        }catch(InterruptedException e) {
            System.out.println(e);
        }
        
        System.out.println("Total " + myRunnable.getValue());
    }

}
class ContadorSynchronized2 implements Runnable{
    private int count=0;
    private boolean stop=false;
    public synchronized int increment() {
        return this.count++;
    }
    public synchronized int getValue() {
        return this.count;
    }
    public void stopped() {
//  public synchronized void stopped() {
        this.stop = true;
    }
    
    @Override
    public synchronized void run() {
        String threadName = Thread.currentThread().getName();//Obtenemos el nombre del hilo
        while(!this.stop) {
            increment();
            System.out.println("Running Thread " + threadName + " increment to: " + getValue());
            try{
                Thread.sleep(100);
            }catch(InterruptedException e) {
                System.out.println(e);
            }
            
            
        }
    }
}
Tarea.java44 líneas

Programas_P2/unam.fc.concurrent.practica2/src/unam/fc/concurrent/practica2/Tarea.java

package unam.fc.concurrent.practica2;

import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Tarea implements Runnable{
    int tiempoTarea;
    int task;
//  final Semaphore smphre;
//  Lock lock = new ReentrantLock();
    public Tarea(int i) {
        this.task = i;
    }
    
    @Override
    public void run() {
        Thread currentThread = Thread.currentThread();
        long id = currentThread.getId();
        
            int value = (int) (id % 6);
            System.out.println("Running Thread " + value + " task: " + this.task);
            switch(value) {
              case 0, 2:
                  this.tiempoTarea = 500;
                break;
              case 1:
                  this.tiempoTarea = 2000;
                break;
              default:
                  this.tiempoTarea = 3000;
            }
            
            try{
                Thread.sleep(this.tiempoTarea);
            }catch(InterruptedException e) {
                System.out.println(e);
            }
            
            System.out.println("Running Thread " + value + " time: " + this.tiempoTarea);
        
    }
}