Códigos del curso

Práctica 5 — Monitores: candados y condiciones

6 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

Del enunciado

Estos tres salen del propio enunciado. Se les añadieron los imports, un constructor para LockedQueue y los métodos de Lock que el PDF omite, para que compilen tal cual.

LockedQueue.java54 líneas
/*
 * LockedQueue.java
 *
 * Monitor con dos variables de condicion: cola acotada de productores/consumidores.
 * Tomado de la Practica 5 (Monitores: candados y condiciones), Computo Concurrente 2026.
 *
 * Basado en "The Art of Multiprocessor Programming", Herlihy y Shavit, Cap. 8.
 */

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

public class LockedQueue<T> {
    final Lock lock = new ReentrantLock();
    final Condition notFull  = lock.newCondition();
    final Condition notEmpty = lock.newCondition();
    final T[] items;
    int tail, head, count;

    @SuppressWarnings("unchecked")
    public LockedQueue(int capacity) {
        items = (T[]) new Object[capacity];
        head = 0;
        tail = 0;
        count = 0;
    }

    public void enq(T x) throws InterruptedException {
        lock.lock();
        try {
            while (count == items.length)
                notFull.await();               // duerme productor
            items[tail] = x;
            if (++tail == items.length) tail = 0;
            ++count;
            notEmpty.signal();                 // avisa consumidor
        } finally { lock.unlock(); }
    }

    public T deq() throws InterruptedException {
        lock.lock();
        try {
            while (count == 0)
                notEmpty.await();              // duerme consumidor
            T x = items[head];
            if (++head == items.length) head = 0;
            --count;
            notFull.signal();                  // avisa productor
            return x;
        } finally { lock.unlock(); }
    }
}
ReadWriteLock.java14 líneas
/*
 * ReadWriteLock.java
 *
 * Interfaz de un candado de lectores/escritores.
 * Tomada de la Practica 5 (Monitores: candados y condiciones), Computo Concurrente 2026.
 */

import java.util.concurrent.locks.Lock;

public interface ReadWriteLock {
    Lock readLock();
    Lock writeLock();
}
SimpleReadWriteLock.java90 líneas
/*
 * SimpleReadWriteLock.java
 *
 * Candado de lectores/escritores con un monitor global.
 * Tomado de la Practica 5 (Monitores: candados y condiciones), Computo Concurrente 2026.
 *
 * Basado en "The Art of Multiprocessor Programming", Herlihy y Shavit, Cap. 8.
 *
 * NOTA: en el enunciado se omiten los metodos restantes de la interfaz Lock y el
 * manejo de InterruptedException. Aqui se incluyen para que la clase compile tal cual;
 * los metodos no usados lanzan UnsupportedOperationException.
 */

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SimpleReadWriteLock implements ReadWriteLock {
    int readers;          // lectores activos
    boolean writer;       // escritor activo
    Lock lock;
    Condition condition;  // monitor global
    Lock readLock, writeLock;

    public SimpleReadWriteLock() {
        writer = false;
        readers = 0;
        lock = new ReentrantLock();
        readLock = new ReadLock();
        writeLock = new WriteLock();
        condition = lock.newCondition();
    }

    public Lock readLock()  { return readLock; }
    public Lock writeLock() { return writeLock; }

    class ReadLock implements Lock {
        public void lock() {
            SimpleReadWriteLock.this.lock.lock();
            try {
                while (writer) condition.await();
                readers++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally { SimpleReadWriteLock.this.lock.unlock(); }
        }

        public void unlock() {
            SimpleReadWriteLock.this.lock.lock();
            try {
                readers--;
                if (readers == 0) condition.signalAll();
            } finally { SimpleReadWriteLock.this.lock.unlock(); }
        }

        // demas metodos de Lock omitidos en el enunciado
        public void lockInterruptibly() { throw new UnsupportedOperationException(); }
        public boolean tryLock() { throw new UnsupportedOperationException(); }
        public boolean tryLock(long time, TimeUnit unit) { throw new UnsupportedOperationException(); }
        public Condition newCondition() { throw new UnsupportedOperationException(); }
    }

    class WriteLock implements Lock {
        public void lock() {
            SimpleReadWriteLock.this.lock.lock();
            try {
                while (readers > 0 || writer) condition.await();
                writer = true;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally { SimpleReadWriteLock.this.lock.unlock(); }
        }

        public void unlock() {
            SimpleReadWriteLock.this.lock.lock();
            try {
                writer = false;
                condition.signalAll();
            } finally { SimpleReadWriteLock.this.lock.unlock(); }
        }

        // demas metodos de Lock omitidos en el enunciado
        public void lockInterruptibly() { throw new UnsupportedOperationException(); }
        public boolean tryLock() { throw new UnsupportedOperationException(); }
        public boolean tryLock(long time, TimeUnit unit) { throw new UnsupportedOperationException(); }
        public Condition newCondition() { throw new UnsupportedOperationException(); }
    }
}

En el repositorio

CountDownLatch.java58 líneas

Programas_P6/unam.fc.concurrent.practica6/src/unam/fc/concurrent/practica6/CountDownLatch.java

package unam.fc.concurrent.practica6;

/*
 * CountDownLatch.java
 *
 * Created on August 27, 2006, 9:03 PM
 *
 * From "The Art of Multiprocessor Programming",
 * by Maurice Herlihy and Nir Shavit.
 * Copyright 2006 Elsevier Inc. All rights reserved.
 */

import java.util.concurrent.locks.*;
import java.util.concurrent.atomic.*;

/**
 * Faux implementation of CountDownLatch from java.util.concurrent.
 *
 * @author Maurice Herlihy
 */

public class CountDownLatch {
  int counter;
  Lock lock;
  Condition condition;
  public CountDownLatch(int count) {
    if (count < 0)
      throw new IllegalArgumentException("count < 0");
    counter = count;
    lock = new ReentrantLock();
    condition = lock.newCondition();
  }
  
  public void await() throws InterruptedException {
    lock.lock();
    try {
      while (counter > 0)
        condition.await();
    } finally {
      lock.unlock();
    }
  }
  
  public void countDown() {
    lock.lock();
    try {
      counter--;
      if (counter == 0) {
        condition.signalAll();
      }
    } finally {
      lock.unlock();
    }
  }
}

ExecReadersWriters.java75 líneas

Programas_P6/unam.fc.concurrent.practica6/src/unam/fc/concurrent/practica6/ExecReadersWriters.java

package unam.fc.concurrent.practica6;

/*
 * Programa que ejecuta FifoReadWriteLock
 */

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


public class ExecReadersWriters {
    int counter = 0;
    static AtomicInteger counterWriters = new AtomicInteger(0);
    static AtomicInteger counterReaders = new AtomicInteger(0);
    private static void taskR(FifoReadWriteLock rw) {//Runnable para el lock Read
        String threadName = Thread.currentThread().getName();//Obtenemos el nombre del hilo
        try {
            rw.readLock().lock();
            System.out.println("Running Reader Thread En: " + threadName);
            System.out.println(counterReaders.incrementAndGet());
        }finally {
            rw.readLock().unlock(); 
            System.out.println(counterReaders.decrementAndGet());
            System.out.println("Running Reader Thread - Salio: " + threadName);
            
            
        }
    }

    private static void taskW(FifoReadWriteLock rw) {//Runnable para el lock Write
        String threadName = Thread.currentThread().getName();//Obtenemos el nombre del hilo
        try {
            rw.writeLock().lock();  
            System.out.println("Running Writer Thread En: " + threadName);
            //System.out.println(counterWriters.incrementAndGet());// Mas de un writer en la SC?
        }finally {
            rw.writeLock().unlock();    
            //System.out.println(counterWriters.decrementAndGet());
            System.out.println("Running Writer Thread - Salio: " + threadName);          
        }
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        FifoReadWriteLock rwLock = new FifoReadWriteLock(); 
        ExecutorService executor = Executors.newFixedThreadPool(6);//El candado solo funciona para dos hilos
        
        
        executor.execute(() -> taskR(rwLock)); 

        executor.execute(() -> taskW(rwLock)); 
        
        executor.execute(() -> taskR(rwLock)); 
        executor.execute(() -> taskR(rwLock)); 
        executor.execute(() -> taskR(rwLock)); 
        
        executor.execute(() -> taskW(rwLock)); 
        executor.execute(() -> taskW(rwLock));
        executor.execute(() -> taskW(rwLock));

        executor.execute(() -> taskR(rwLock)); 
        executor.execute(() -> taskR(rwLock)); 
        executor.execute(() -> taskR(rwLock)); 
        executor.execute(() -> taskR(rwLock)); 

        executor.shutdown();
        
        //while(!executor.isTerminated()) {};

    
    }
}
FifoReadWriteLock.java143 líneas

Programas_P6/unam.fc.concurrent.practica6/src/unam/fc/concurrent/practica6/FifoReadWriteLock.java

package unam.fc.concurrent.practica6;

/*
 * FIFOReadWriteLock.java
 *
 * Created on January 9, 2006, 7:39 PM
 *
 * From "Multiprocessor Synchronization and Concurrent Data Structures",
 * by Maurice Herlihy and Nir Shavit.
 * Copyright 2006 Elsevier Inc. All rights reserved.
 * 
 * Modified 3nov24 Gilde Valeria R.
 */


import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * First-in First-out readers/writers lock.
 * @author Maurice Herlihy
 */
public class FifoReadWriteLock implements ReadWriteLock {
  int readAcquires; // read acquires since start
  int readReleases; // read releses since start
  boolean writer;   // writer present?
  Lock metaLock;    // short-term synchronization
  Condition condition;
  Lock readLock;    // readers apply here
  Lock writeLock;   // writers apply here
  
  public FifoReadWriteLock() {
    readAcquires = readReleases = 0;
    writer    = false;
    metaLock  = new ReentrantLock();
    condition = metaLock.newCondition();
    readLock  = new ReadLock();
    writeLock = new WriteLock();
  }
  
  public Lock readLock() {
    return readLock;
  }
  
  public Lock writeLock() {
    return writeLock;
  }
  private class ReadLock implements Lock {
    public void lock() {
      metaLock.lock();
      try {
        
        //System.out.println("Lock ReadAcquires: " + readAcquires + " ReadReleases: " + readReleases);
        
        while (writer) {
          try {
            condition.await();
          } catch (InterruptedException ex) {
            // do something application-specific
          }
          
        }
        //System.out.println("Writer: " + writer);
        readAcquires++;
      } finally {
        metaLock.unlock();
      }
    }
    public void unlock() {
      metaLock.lock();
      try {
        readReleases++;
        //System.out.println("Unlock ReadAcquires: " + readAcquires + " ReadReleases: " + readReleases);

        if (readAcquires == readReleases)
          condition.signalAll();
      } finally {
        metaLock.unlock();
      }
    }
    public void lockInterruptibly() throws InterruptedException {
      throw new UnsupportedOperationException();
    }
    
    public boolean tryLock() {
      throw new UnsupportedOperationException();
    }
    
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
      throw new UnsupportedOperationException();
    }
    
    public Condition newCondition() {
      throw new UnsupportedOperationException();
    }
  }
  private class WriteLock implements Lock {
    public void lock() {
      metaLock.lock();
      try {
        while (writer)
          try {
            condition.await();
          } catch (InterruptedException e) {}
        
        writer = true;

        while (readAcquires != readReleases)
          try {
            condition.await();
          } catch (InterruptedException e) {}
        
        //System.out.println("Writer: " + writer);

      } finally {
        metaLock.unlock();
      }
    }
    public void unlock() {
      
      writer = false;
      //System.out.println("Writer: " + writer);
    }
    public void lockInterruptibly() throws InterruptedException {
      throw new UnsupportedOperationException();
    }
    
    public boolean tryLock() {
      throw new UnsupportedOperationException();
    }
    
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
      throw new UnsupportedOperationException();
    }
    
    public Condition newCondition() {
      throw new UnsupportedOperationException();
    }
  }
}