package ar.com.javacuriosities.threads;
public class Lesson15ThreadLocal {
public static void main(String[] args) {
try {
// Creamos un recurso compartido
SharedResource sharedResource = new SharedResource();
// Creamos 3 thread que comparten el mismo recurso
Thread thread1 = new Thread(new Task(20, sharedResource));
Thread thread2 = new Thread(new Task(30, sharedResource));
Thread thread3 = new Thread(new Task(50, sharedResource));
thread1.setName("Thread-01 (20 Tasks)");
thread2.setName("Thread-02 (30 Tasks)");
thread3.setName("Thread-03 (50 Tasks)");
// Iniciamos cada hilo
thread1.start();
thread2.start();
thread3.start();
thread1.join();
thread2.join();
thread3.join();
} catch (InterruptedException e) {
// Log and Handle exception
e.printStackTrace();
}
}
/*
* Esta clase simula un recurso compartido el cual será usado por varios threads,
* el mismo posee dos atributos el cual uno se encuentra usando ThreadLocal lo cual
* implica que cada Thread tendrá su propio valor
*/
private static final class SharedResource {
private int counter = 0;
private ThreadLocal<Integer> localCounter = new ThreadLocal<Integer>();
public SharedResource() {
}
public int getCounter() {
return counter;
}
/*
* Este método devuelve el valor del contador asociado al hilo actual
*/
public Integer getLocalCounter() {
if (localCounter.get() == null) {
localCounter.set(Integer.valueOf(0));
}
return localCounter.get();
}
public synchronized void incrementCounter() {
counter++;
}
public synchronized void incrementLocalCounter() {
localCounter.set(getLocalCounter() + 1);
}
}
/*
* Esta tarea utiliza un recurso compartido sobre el cual incrementa el valor de las propiedades
* del recurso
*/
private static final class Task implements Runnable {
private int loopCounter;
private SharedResource sharedResource;
public Task(int loopCounter, SharedResource sharedResource) {
this.loopCounter = loopCounter;
this.sharedResource = sharedResource;
}
@Override
public void run() {
for (int i = 1; i <= loopCounter; i++) {
sharedResource.incrementCounter();
sharedResource.incrementLocalCounter();
}
String threadName = Thread.currentThread().getName();
/*
* Aquí imprimimos el valor de la variable que es compartida por todos los threads
*/
System.out.println("Thread:" + threadName + " Counter value: " + sharedResource.getCounter());
/*
* Aquí imprimimos el valor del contador local porque este esta definido como ThreadLocal
* o sea cada thread que lo usa tiene su propio valor por eso es que el máximo valor de cada contador
* local es el máximo numero de iteraciones
*/
System.out.println("Thread:" + threadName + " Local counter value: " + sharedResource.getLocalCounter());
}
}
}