Puedes copiar cada archivo desde aquí, o clonar el repositorio FC_CConcurrente completo:
git clone https://github.com/gilde-valeria/FC_CConcurrente.gitArchivos
Archivos
module-info.java
Programas_P3/unam.fc.concurrent.practica3/src/module-info.java
/**
*
*/
/**
*
*/
module unam.fc.concurrent.practica3 {
}
Bakery.java
Programas_P3/unam.fc.concurrent.practica3/src/unam/fc/concurrent/practica3/Bakery.java
package unam.fc.concurrent.practica3;
import java.util.concurrent.atomic.*;
//Programa 5: Lamport's algorithm Unbounded
import unam.fc.concurrent.practica3.Nodo;
public class Bakery {
private Nodo head;
private Nodo tail;
public Bakery() {
this.head = new Nodo(false, 0);
this.tail = new Nodo(false, 10000);
while (!this.head.next.compareAndSet(null, this.tail));
}
public void lock(Nodo newnode) {
Boolean added = false;
Nodo last = null;
while (!added) {
if (this.tail.next.get() == null) {
added = this.head.next.compareAndSet(this.tail, newnode);
if (added) {
this.tail.next.compareAndSet(null, newnode);
last = head;
}
}else {
last = this.tail.next.get();
added = last.next.compareAndSet(null, newnode);
tail.next.compareAndSet(last, newnode);
}
}
while (last.flag == true) {};
}
public void unlock(Nodo newnode) {
newnode.flag = false;
}
public void print() {
Nodo pred = this.head;
Nodo curr = pred.next.get();
System.out.println(pred.item);
while (curr != null) {
pred = curr;
curr = curr.next.get();
System.out.println(pred.item);
}
}
}
CounterNaive.java
Programas_P3/unam.fc.concurrent.practica3/src/unam/fc/concurrent/practica3/CounterNaive.java
package unam.fc.concurrent.practica3;
public class CounterNaive {
private int count=0;
public int increment() {
return this.count++;
}
public int getValue() {
return this.count;
}
}
ExecuteBakery.java
Programas_P3/unam.fc.concurrent.practica3/src/unam/fc/concurrent/practica3/ExecuteBakery.java
package unam.fc.concurrent.practica3;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//Programa 4: Programa que ejecuta la clase Lamport's Bakery
// Este programa utiliza a su vez la clase Nodo
public class ExecuteBakery {
public static void take(Bakery lock, CounterNaive counter) {
Thread currentThread = Thread.currentThread();
long id = currentThread.getId();
Nodo node = new Nodo(true, (int) (id));
try {
lock.lock(node);
Thread.sleep(5);
counter.increment();
//System.out.println("in ");
}catch(InterruptedException e) {
System.out.println(e);
}finally {
lock.unlock(node);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Bakery lock = new Bakery();
CounterNaive counter= new CounterNaive();
ExecutorService executor = Executors.newFixedThreadPool(5);
for(int i = 0; i < 400; i++) {
executor.execute(() -> take(lock, counter)); //Runnable al estilo lambda, esta notacion se usa en interfaces
}
try {
Thread.sleep(5000);
lock.print();
System.out.println(counter.getValue());
}catch(InterruptedException e) {
System.out.println(e);
}
}
}
LockPeterson.java
Programas_P3/unam.fc.concurrent.practica3/src/unam/fc/concurrent/practica3/LockPeterson.java
package unam.fc.concurrent.practica3;
//Programa 3: Programa que ejecuta la clase Peterson, todas las variables utilizan volatile
// Utiliza la clase CounterNaive
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class LockPeterson{
private static void task(Peterson lock, CounterNaive counter) {
try {
lock.lock();
counter.increment();
// System.out.println(counter.getValue());
}finally {
lock.unlock();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Peterson lock = new Peterson();
CounterNaive counter = new CounterNaive();
ExecutorService executor = Executors.newFixedThreadPool(2);//El candado solo funciona para dos hilos
for(int i = 0; i < 1000; i++) {
executor.execute(() -> task(lock,counter));
}
executor.shutdown();
try{
Thread.sleep(500);
System.out.println(counter.getValue());
}catch(InterruptedException e) {
System.out.println(e);
}
}
}
Nodo.java
Programas_P3/unam.fc.concurrent.practica3/src/unam/fc/concurrent/practica3/Nodo.java
package unam.fc.concurrent.practica3;
import java.util.concurrent.atomic.AtomicReference;
public class Nodo {
public volatile Boolean flag; // Bandera que es true si quiero pasar y false si ya pase
public AtomicReference<Nodo> next;
public int item;
public Nodo(Boolean flag, int item) {
this.flag = flag;
this.item = item;
this.next = new AtomicReference<Nodo>(null);
}
}
Peterson.java
Programas_P3/unam.fc.concurrent.practica3/src/unam/fc/concurrent/practica3/Peterson.java
package unam.fc.concurrent.practica3;
public class Peterson {
private volatile boolean[] flag = new boolean[2];
private volatile int victim;
public void Peterson() {
flag[0] = false; flag[1] = false;
victim = 3;
}
public void lock() {
Thread currentThread = Thread.currentThread();
long id = currentThread.getId();
int i = (int) (id % 2);
int j = 1-i;
flag[i] = true;
victim = i;
while (flag[j] && victim == i) {
};
}
public void unlock() {
Thread currentThread = Thread.currentThread();
long id = currentThread.getId();
int i = (int) (id % 2);
flag[i] = false;
}
}
VolatileExample1.java
Programas_P3/unam.fc.concurrent.practica3/src/unam/fc/concurrent/practica3/VolatileExample1.java
package unam.fc.concurrent.practica3;
//Programa 1: Programa que ejemplifica el problema de Visibilidad en el JMM
// Si la variable flag no es volatile, entonces el hilo que ejecuta read() puede nunca leer que el
// hilo que ejecuta write() modifico flag
// Implica que volatile hace flush! a las modificaciones de flag
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class VolatileExample1 {
static Boolean flag = false;
private static void read() {
while(!flag) {}
System.out.println("La bandera esta en: " + flag);
}
private static void write() {
try {
Thread.sleep(1000);
flag = true;
System.out.println("La bandera fue cambiada a true: " + flag);
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(() -> write());
executor.execute(() -> read());
executor.shutdown();
}
}
VolatileExample2.java
Programas_P3/unam.fc.concurrent.practica3/src/unam/fc/concurrent/practica3/VolatileExample2.java
package unam.fc.concurrent.practica3;
//Programa 2: Programa que ejemplifica el problema de Reordenamiento en el JMM
// Si no se utiliza volatile, entonces las lineas 15 a 18 se reordenan y el resultado de a y b es distinto
// Implica que volatile forza al compilador a no reordenar las instrucciones
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class VolatileExample2 {
static Boolean flag = false;
volatile static int a = 0, b = 0;
private static void read() {
while(!flag) {
a = 0;
b += 1;
b = a;
a += 1;}
System.out.println("La bandera esta en: " + flag + " a: " +a +" b: " + b);
}
private static void write() {
try {
Thread.sleep(1000);
a = b;
b = a;
flag = true;
b += 1;
a += 1;
System.out.println("La bandera fue cambiada a true: " + flag);
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(() -> write());
executor.execute(() -> read());
executor.shutdown();
try {
Thread.sleep(1500);
System.out.println("main: " + flag + " a: " +a +" b: " + b);
} catch (Exception e) {
// TODO: handle exception
}
}
}