5. RENOVACIÓ I INNOVACIÓ DELS CONREUS
5.2 La introducció de nous conreus
5.2.2 Noves plantes oleÍferes: complements per a l’olivera
private static final Random rand = new Random();
private final static Exchanger<Buffer<Character>> exchanger = new Exchanger();
private final static Buffer<Character> buffer1 = new Buffer(15);
private final static Buffer<Character> buffer2 = new Buffer(10);
private static char ch = 'Z';
public static void main(String[] args) {
class Producer implements Runnable {
public void run() {
Buffer<Character> buffer = buffer1;
try {
while (true) {
With us you can shape the future.
Every single day.
For more information go to:
www.eon-career.com
Your energy shapes the future.
JAVA 8:MULTITHREADED PROGRAMS
64
ConCurrenCy tools JAVA 8:MULTITHREADED PROGRAMS
64
COnCURREnCy TOOLS
buffer.insert(next());
Thread.sleep(rand.nextInt(500));
if (buffer.full()) buffer = exchanger.exchange(buffer);
} }
catch (Exception ex) {
System.out.println(ex);
} } }
class Consumer implements Runnable {
public void run() {
Buffer<Character> buffer = buffer2;
try {
while (true) {
Thread.sleep(rand.nextInt(500));
if (buffer.empty()) {
buffer = exchanger.exchange(buffer);
System.out.println();
}
System.out.print(buffer.remove());
} }
catch (Exception ex) {
System.out.println(ex);
} } }
new Thread(new Producer()).start();
new Thread(new Consumer()).start();
}
private static char next() {
if (ch == 'Z') ch = 'A'; else ++ch;
return ch;
} }
JAVA 8:MULTITHREADED PROGRAMS ConCurrenCy tools
8.5 SEMAPHORE
A semaphore manages a number of permits in relation to a number of threads that want to access a shared resource. A thread that is trying to obtain permission for the resource, while all licenses are used, is blocked until another thread releases the license. A semaphore’s value is an integer whose value is not negative and can be counted up or down. If the semaphore can take only the values 0 and 1, we speak of a binary semaphore, and may the value be greater than 1, it is called a counting semaphore. This means that is the access to a resource controlled with a counting semaphore, there are several threads at a time (determined by semaphoren) that can access the resource. The following program will show how to use a semaphore:
JAVA 8:MULTITHREADED PROGRAMS COnCURREnCy TOOLS
8.5 SEMAPHORE
A semaphore manages a number of permits in relation to a number of threads that want to access a shared resource. A thread that is trying to obtain permission for the resource, while all licenses are used, is blocked until another thread releases the license. A semaphore’s value is an integer whose value is not negative and can be counted up or down. If the semaphore can take only the values 0 and 1, we speak of a binary semaphore, and may the value be greater than 1, it is called a counting semaphore. This means that is the access to a resource controlled with a counting semaphore, there are several threads at a time (determined by semaphoren) that can access the resource. The following program will show how to use a semaphore:
package thread19;
import java.util.*;
import java.util.concurrent.*;
public class Thread19 {
public static void main(String[] args) {
final Resources resources = new Resources();
Worker worker = new Worker(resources);
int N = 2 * Resources.N;
ExecutorService executor = Executors.newFixedThreadPool(N);
for (int i = 0; i < N; ++i) executor.execute(worker);
try {
executor.awaitTermination(20, TimeUnit.SECONDS);
}
catch (Exception ex) {
}
executor.shutdownNow();
} }
class Worker implements Runnable {
private static final Random rand = new Random();
private Resources resources;
private long counter = 0;
JAVA 8:MULTITHREADED PROGRAMS
66
ConCurrenCy tools
66 JAVA 8:MULTITHREADED PROGRAMS
66
COnCURREnCy TOOLS
66
public Worker(Resources resources) {
this.resources = resources;
}
public void run() {
try {
while (counter < 100) {
Resource res = resources.getResouce();
System.out.printf("[%d] anvender %s: %3d\n",
Thread.currentThread().getId(), res.toString(), res.getValue());
Thread.sleep(500 + rand.nextInt(500));
res.updateValue(++counter);
resources.putResource(res);
System.out.printf("[%d] opdateret %s: %3d\n",
Thread.currentThread().getId(), res.toString(), res.getValue());
Thread.sleep(500 + rand.nextInt(500));
} }
catch (InterruptedException ex) {
JAVA 8:MULTITHREADED PROGRAMS ConCurrenCy tools
JAVA 8:MULTITHREADED PROGRAMS COnCURREnCy TOOLS
System.out.println(ex);
} } }
class Resources {
public static final int N = 10; // number of Resource objects private final Resource[] resources = new Resource[N];
private final Semaphore sema = new Semaphore(N, true);
private final boolean[] used = new boolean[N];
public Resources() {
for (int i = 0; i < resources.length; ++i) resources[i] = new Resource();
}
public Resource getResouce() throws InterruptedException {
sema.acquire();
return get();
}
public void putResource(Resource res) {
if (unused(res)) sema.release();
}
private synchronized Resource get() {
for (int i = 0; i < N; ++i) {
if (!used[i]) {
used[i] = true;
return resources[i];
} }
return null;
}
private synchronized boolean unused(Resource res) {
for (int i = 0; i < N; ++i) {
if (res.equals(resources[i])) {
JAVA 8:MULTITHREADED PROGRAMS
68
ConCurrenCy tools JAVA 8:MULTITHREADED PROGRAMS
68
COnCURREnCy TOOLS
if (used[i]) {
used[i] = false;
return true;
}
else return false;
} }
return false;
} }
class Resource {
private static int ID = 0;
private int id; // the ressource's id
private long value; // the ressource's value public Resource()
{
id = ++ID;
}
public long getValue() {
return value;
}
public void updateValue(long value) {
this.value += value;
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (getClass() == obj.getClass()) return ((Resource)obj).id == id;
return false;
}
public String toString() {
return String.format("Resource: [%d]", id);
} }
JAVA 8:MULTITHREADED PROGRAMS ConCurrenCy tools
The class Resource is a simple encapsulation of a long and has basically two methods:
1. getValue() that returns the object’s value
2. updateValue(), that adds a value to the object’s value
Each object is assigned also a consecutively number when it is created, and it is only to have an identification of the object and to give the object a name in toString().
The most importannt class is the class Resources, which is an encapsulation of an array of Resource objects. The idea is that a thread may wish to get a Resource object and update it.
While this happens, the object is locked and is released again after it is updated. The class creates a Semaphore to check the threads access to an object:
JAVA 8:MULTITHREADED PROGRAMS COnCURREnCy TOOLS
The class Resource is a simple encapsulation of a long and has basically two methods:
1. getValue() that returns the object’s value
2. updateValue(), that adds a value to the object’s value
Each object is assigned also a consecutively number when it is created, and it is only to have an identification of the object and to give the object a name in toString().
The most importannt class is the class Resources, which is an encapsulation of an array of Resource objects. The idea is that a thread may wish to get a Resource object and update it.
While this happens, the object is locked and is released again after it is updated. The class creates a Semaphore to check the threads access to an object:
private final Semaphore sema = new Semaphore(N, true);