BoundedBuffer.java
- package ch.hslu.exercises.sw06.ex4;
- import java.util.ArrayDeque;
- import java.util.concurrent.Semaphore;
- import java.util.concurrent.TimeUnit;
- /**
- * Puffer nach dem First In First Out Prinzip mit einer begrenzten Kapazität.
- * Der Puffer ist thread sicher.
- *
- * @param <T> Elememente des Buffers
- */
- public final class BoundedBuffer<T> implements Buffer<T> {
- private final ArrayDeque<T> queue;
- private final Semaphore putSema;
- private final Semaphore takeSema;
- /**
- * Erzeugt einen Puffer mit bestimmter Kapazität.
- *
- * @param n Kapazität des Puffers
- */
- public BoundedBuffer(final int n) {
- queue = new ArrayDeque<>(n);
- putSema = new Semaphore(n);
- takeSema = new Semaphore(0);
- }
- @Override
- public void add(final T elem) throws InterruptedException {
- putSema.acquire();
- addSynchronized(elem);
- }
- @Override
- public T remove() throws InterruptedException {
- takeSema.acquire();
- return removeSynchronized();
- }
- @Override
- public boolean add(T elem, long millis) throws InterruptedException {
- if (putSema.tryAcquire(millis, TimeUnit.MILLISECONDS)) {
- addSynchronized(elem);
- return true;
- } else {
- return false;
- }
- }
- @Override
- public T remove(long millis) throws InterruptedException {
- if (takeSema.tryAcquire(millis, TimeUnit.MILLISECONDS)) {
- return removeSynchronized();
- } else {
- return null;
- }
- }
- public void addSynchronized(T elem) {
- synchronized (queue) {
- queue.addFirst(elem);
- }
- takeSema.release();
- }
- private T removeSynchronized() {
- T elem;
- synchronized (queue) {
- elem = queue.removeLast();
- }
- putSema.release();
- return elem;
- }
- @Override
- public boolean empty() {
- return takeSema.availablePermits() == 0;
- }
- @Override
- public boolean full() {
- return putSema.availablePermits() == 0;
- }
- @Override
- public int size() {
- return takeSema.availablePermits();
- }
- }