Java Concurrency: Threads, Runnables, and Synchronization
Class Acumulador
This class implements a synchronized counter.
public class Acumulador implements Comparable<Acumulador> {
private int acumulador;
private final int id;
public Acumulador(int id) {
this.id = id;
}
public int getAcumulador() {
return acumulador;
}
public synchronized void addAcumulador(int puntuacio) {
this.acumulador += puntuacio;
}
public int getId() {
return id;
}
@Override
public int compareTo(Acumulador t) {
return t.acumulador - acumulador;
}
}
Class Enfrontament
This class simulates a confrontation between two Acumulador
objects.
public class Enfrontament extends Thread {
private Acumulador a1;
private Acumulador a2;
public Enfrontament(Acumulador a1, Acumulador a2) {
this.a1 = a1;
this.a2 = a2;
}
@Override
public void run() {
try {
sleep((long) (Math.random() * 2000));
play();
} catch (InterruptedException ex) {
Logger.getLogger(Enfrontament.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void play() {
int p1 = 0;
int p2 = 0;
for (int i = 0; i < 1000; i++) {
if (Math.random() < 0.5) {
p1++;
} else {
p2++;
}
}
a1.addAcumulador(p1);
a2.addAcumulador(p2);
}
}
Main Method for Enfrontament
public static void main(String[] args) {
ArrayList<Acumulador> llista = new ArrayList<>();
for (int i = 0; i < 10; i++) {
llista.add(new Acumulador(i));
}
for (int i = 0; i < llista.size() - 1; i++) {
for (int j = i + 1; j < llista.size(); j++) {
Enfrontament e = new Enfrontament(llista.get(i), llista.get(j));
e.start();
}
}
ThreadGroup group = Thread.currentThread().getThreadGroup();
while (group.activeCount() > 1) {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
Object[] array = llista.toArray();
Arrays.sort(array);
for (int i = 0; i < array.length; i++) {
Acumulador a = (Acumulador) array[i];
System.out.println(i + "=" + a.getId() + ":" + a.getAcumulador());
}
}
Class ConcurrentID
This class demonstrates concurrent execution using Thread
.
public class ConcurrentID extends Thread {
private static int count = 0;
private int id;
public ConcurrentID() {
count++;
id = count;
}
@Override
public String toString() {
return "ConcurrentID{" + id + '}';
}
@Override
public void run() {
try {
// Here concurrent execution will begin
sleep((long) (Math.random() * 2000));
System.out.println("El procés " + id + " s'ha despertat");
// Here concurrent execution ends
} catch (InterruptedException ex) {
Logger.getLogger(ConcurrentID.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Class ConcurrentIDRunnable
This class demonstrates concurrent execution using Runnable
.
public class ConcurrentIDRunnable implements Runnable {
private static int count = 0;
private int id;
public ConcurrentIDRunnable() {
count++;
id = count;
}
public void run() {
try {
Thread.sleep((long) (Math.random() * 5000));
System.out.println("El procés " + id + " s'ha despertat");
} catch (InterruptedException ex) {
Logger.getLogger(ConcurrentIDRunnable.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Class ConcurrentSincronitzada
This class demonstrates synchronized access to a shared attribute.
public class ConcurrentSincronitzada extends Thread {
private static int count = 0;
private int id;
private static int attCompartit = 0;
public ConcurrentSincronitzada() {
count++;
id = count;
}
public static synchronized void update(int id) {
attCompartit = attCompartit + 1;
System.out.println(id + "#" + attCompartit);
}
@Override
public void run() {
try {
sleep((long) (1000));
update(id);
} catch (InterruptedException ex) {
Logger.getLogger(ConcurrentSincronitzada.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Class Missatge
This class represents a message object used for inter-thread communication.
public class Missatge {
private String contingut;
public Missatge() {
contingut = "pendent";
}
public String getContingut() {
return contingut;
}
public void setContingut(String contingut) {
this.contingut = contingut;
}
}
Class Escriptor
This class writes messages to a Missatge
object.
public class Escriptor extends Thread {
private Missatge m;
public Escriptor(Missatge m) {
this.m = m;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
sleep((long) (Math.random() * 1000));
synchronized (m) {
m.setContingut("Transferència Missatge " + i);
m.notifyAll();
}
} catch (InterruptedException ex) {
Logger.getLogger(Escriptor.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Class Lector
This class reads messages from a Missatge
object.
public class Lector extends Thread {
private Missatge m;
private int id;
public Lector(Missatge m, int id) {
this.m = m;
this.id = id;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
synchronized (m) {
m.wait();
System.out.println("Lector " + id + ": " + m.getContingut());
}
} catch (InterruptedException ex) {
Logger.getLogger(Lector.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Main Method for Cooperative Threads
public static void main(String[] args) {
// Cooperative work of threads
Missatge m = new Missatge();
Escriptor e = new Escriptor(m);
Lector l1 = new Lector(m, 1);
Lector l2 = new Lector(m, 2);
e.start();
l1.start();
l2.start();
}
Class Concurrent
This class demonstrates synchronized modification of a static accumulator.
public class Concurrent extends Thread {
private static int acumulador;
private int id;
public Concurrent(int id) {
this.id = id;
}
public static synchronized void modificaAcc() {
acumulador = acumulador + 1;
System.out.println("Procés =" + acumulador);
}
@Override
public void run() {
for (int i = 0; i < 200; i++) {
try {
this.sleep(50);
} catch (InterruptedException ex) {
Logger.getLogger(Concurrent.class.getName()).log(Level.SEVERE, null, ex);
}
modificaAcc();
}
}
}
Main Method for Concurrent Class
public class Main {
public static void main(String[] args) {
Concurrent c1 = new Concurrent(1);
Concurrent c2 = new Concurrent(2);
c1.start();
c2.start();
}
}
Class Contenidor
This class represents a container for a message.
public class Contenidor {
private String missatge;
public String getMissatge() {
return missatge;
}
public void setMissatge(String missatge) {
this.missatge = missatge;
}
}
Class Escriptor for Contenidor
This class writes messages to a Contenidor
object.
public class Escriptor extends Thread {
private Contenidor c;
public Escriptor(Contenidor c) {
this.c = c;
}
@Override
public void run() {
int i = 1;
while (true) {
try {
double rnd = Math.random();
rnd += 1;
rnd *= 1000;
Thread.sleep((long) rnd);
synchronized (c) {
c.setMissatge("Missatge " + i);
i++;
c.notifyAll();
}
} catch (InterruptedException ex) {
Logger.getLogger(Escriptor.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Class Lector for Contenidor
This class reads messages from a Contenidor
object.
public class Lector extends Thread {
private Contenidor c;
private int id;
public Lector(Contenidor c, int id) {
this.c = c;
this.id = id;
}
@Override
public void run() {
while (true) {
try {
synchronized (c) {
c.wait();
System.out.println("El lector " + id + ":" + c.getMissatge());
}
} catch (InterruptedException ex) {
Logger.getLogger(Lector.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Main Method for Contenidor Example
public class Main {
public static void main(String[] args) {
Contenidor c = new Contenidor();
Escriptor e = new Escriptor(c);
Lector l1 = new Lector(c, 10);
Lector l2 = new Lector(c, 20);
Lector l3 = new Lector(c, 30);
e.start();
l1.start();
l2.start();
l3.start();
}
}
Class ConcurrentRunnable
This class demonstrates a simple concurrent runnable.
public class ConcurrentRunnable extends Object implements Runnable {
public void run() {
while (true) {
try {
Thread.sleep((long) (Math.random() * 100));
} catch (InterruptedException ex) {
Logger.getLogger(Concurrent.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Salutació del procés Runnable");
}
}
}
Main Method for Concurrent and ConcurrentRunnable
public static void main(String[] args) {
try {
Concurrent c1 = new Concurrent(1);
Concurrent c2 = new Concurrent(2);
c1.setPriority(Thread.MAX_PRIORITY);
c2.setPriority(Thread.MIN_PRIORITY);
ConcurrentRunnable cr = new ConcurrentRunnable();
c1.start();
c2.start();
// Thread th = new Thread(cr);
// th.setDaemon(true);
// th.start();
Thread.sleep(2000);
c1.setId(10);
Thread.sleep(1000);
c2.setId(20);
System.out.println("El procés del main ja ha acabat");
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}