Об этой очереди. Вы можете использовать ExecutorService
для этого.
Разрешение Хеджу расти
Итак, у вас есть живая изгородь, которая может расти и обрезаться.
class Hedge {
private AtomicInteger height = new AtomicInteger(1);
public int grow() {
return height.incrementAndGet();
}
public int cut() {
return height.decrementAndGet();
}
}
И тогда у вас будет среда, которая позволит хеджу расти. Это будет имитировать участки хеджирования; каждая среда отвечает только за один из разделов. Он также уведомит Consumer<Integer>
об изменении размера хеджирования.
class SectionGrower implements Runnable {
public static final Random RANDOM = new Random();
private final Hedge hedge;
private final Consumer<Integer> hedgeSizeListener;
public SectionGrower (Hedge h, Consumer<Integer> hl) {
hedge = h;
hedgeSizeListener = hl
}
public void run() {
while (true) { // grow forever
try {
// growing the hedge takes up to 20 seconds
Thread.sleep(RANDOM.nextInt(20)*1000);
int sectionHeight = hedge.grow();
hedgeSizeListener.accept(sectionHeight);
} catch (Exception e) {} // do something here
}
}
}
Итак, на данный момент, вы можете сделать это.
ExecutorService growingExecutor = Executors.newFixedThreadPool(10);
Consumer<Integer> printer = i -> System.out.printf("hedge section has grown to %d\n", i.intValue());
for (int i = 0; i < 10; i++) {
Hedge section = new Hedge();
Environment grower = new SectionGrower(section, printer);
growingExecutor.submit(grower::run);
}
Это увеличит 10 секций хеджирования и напечатает текущую высоту для каждой по мере их роста.
Добавление садовника
Так что теперь вам нужен Садовник, который может срезать живую изгородь.
class Gardener {
public static final Random RANDOM = new Random();
public void cutHedge(Hedge h) {
try {
// cutting the hedge takes up to 10 seconds
Thread.sleep(RANDOM.nextInt(10)*1000);
h.cut();
} catch (Exception e) {} // do something here
}
}
Теперь вам нужна какая-то конструкция, чтобы дать ему работу; это то место, где приходит BlockingQueue
. Мы уже убедились, что Environment
может уведомить Consumer<Integer>
после того, как раздел вырос, так что это то, что мы можем использовать.
ExecutorService growingExecutor = Executors.newFixedThreadPool(10);
// so this is the queue
ExecutorService gardenerExecutor = Executors.newSingleThreadPool();
Gardener gardener = new Gardener();
for (int i = 0; i < 10; i++) {
Hedge section = new Hedge();
Consumer<Integer> cutSectionIfNeeded = i -> {
if (i > 8) { // size exceeded?
// have the gardener cut the section, ie adding item to queue
gardenerExecutor.submit(() -> gardener.cutHedge(section));
}
};
SectionGrower grower = new SectionGrower(section, cutSectionIfNeeded);
growingExecutor.submit(grower::run);
}
Так что я на самом деле не пробовал это, но он должен работать с некоторыми небольшими изменениями.
Обратите внимание, что я использую AtomicInteger
в хеджировании, потому что он может расти и обрезаться "одновременно", потому что это происходит в разных потоках.