Кто понял? Объясните как и для чего использовать семафоры желательно на примере.
//Fat.java
public class Fat {
private volatile double d; // Предотвращает оптимизацию
private static int counter = 0;
private final int id = counter++;
public Fat() {
// нагрузка
for(int i = 1; i < 10000; i++)
d += (Math.PI + Math.E) / (double)i;
}
public void operation() { System.out.println(this); }
public String toString() { return "Fat id: " + id; }
}
import java.util.concurrent.*;
import java.util.*;
import static net.mindview.util.Print.*;
class CheckoutTask implements Runnable {
private static int counter = 0;
private final int id = counter++;
private Pool pool;
public CheckoutTask(Pool pool) {
this.pool = pool;
}
public void run() {
try {
T item = pool.checkOut();
print(this + "checked out " + item);
TimeUnit.SECONDS.sleep(1);
print(this +"checking in " + item);
pool.checkIn(item);
} catch(InterruptedException e) {}
}
public String toString() {
return "CheckoutTask " + id + " ";
}
}
public class SemaphoreDemo {
final static int SIZE = 25;
public static void main(String[] args) throws Exception {
final Pool pool = new Pool(Fat.class, SIZE);
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < SIZE; i++)
exec.execute(new CheckoutTask(pool));
print("All CheckoutTasks created");
List list = new ArrayList();
for(int i = 0; i < SIZE; i++) {
Fat f = pool.checkOut();
printnb(i + ": main() thread checked out ");
f.operation();
list.add(f);
}
Future> blocked = exec.submit(new Runnable() {
public void run() {
try {
pool.checkOut();
} catch(InterruptedException e) {
print("checkOut() Interrupted");
}
}
});
TimeUnit.SECONDS.sleep(2);
blocked.cancel(true); // Выход из заблокированного вызова
print("Checking in objects in " + list);
for(Fat f : list)
pool.checkIn(f);
for(Fat f : list)
pool.checkIn(f); // Второй вызов checkIn игнорируется
exec.shutdown();
}
}
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Один из способов обьяснить как работает семафор это предавить его как некое «разрешение». Только один процесс/поток может одновременно получить и держать это «разрешение», которое уще нужно успеть достать, прежде чем процессу будет разрешено попасть в критическую область кода. Как только поток закончил свою работу он может вернуть разрешение.
Вобщем рисунок не мой, из книги. Неплохо так нарисовано. Думаю разберешся как примерно семафор обслуживает клиентов.