многопоточность – Реализация семафора Java на русском
многопоточность – Реализация семафора Java на русском
Хотя конечно варианты реализации семафоров лучше в книгах по многопоточности посмотреть, вот вариант велосипеда:
public class TestSemaphor {
private final static int NThreads = 60;
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
Thread[] threads = new Thread[NThreads];
for (int i = 0; i < NThreads; i++) {
threads[i] = new Thread(new Runner(semaphore, i));
}
for (int i = 0; i < NThreads; i++) {
threads[i].start();
}
}
}
class Runner implements Runnable {
private Semaphore semaphore;
private int label;
public Runner(Semaphore semaphore, int label) {
this.semaphore = semaphore;
this.label = label;
}
@Override
public void run() {
int r = 0;
System.out.println(thread + label + start);
semaphore.enter();
System.out.println(thread + label + is working);
for (int k = 0; k < 10000; k++) {
r = new Random().nextInt();
}
;
System.out.println(thread + label + has ended work);
semaphore.leave();
System.out.println(thread + label + end + r);
}
}
class Semaphore {
private int curMax;
private int cur;
private Object lock = new Object();
public Semaphore(int curMax) {
this.curMax = curMax;
}
public void enter() {
synchronized (lock) {
cur++;
if (cur > curMax) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public void leave() {
synchronized (lock) {
cur--;
lock.notify();
}
}
}
Собственно идея такая: синхронизации используется только для того, чтобы обновить счетчик очереди. Если при этом у нас потоков больше чем надо, то отправляем текущий поток в ожидание. При освобождении семафора вызываем на случайном ожидающем потоке notify. Обратите внимание что синхронизация идет по одному и тому же объекту – поэтому happens before присутствует