import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * {@link <a href=
 * "https://[Log in to view URL]"
 * target= "_blank">sincronizzazione estesa di un thread pool</a>}
 * 
 * @author itammb ( Italia Massimiliano Buscati )
 * @version JDK 1.15
 *
 */
class Main {
	private static class BoundedBuffer<E> {
		private final Lock lock = new ReentrantLock();
		private final Condition notFull = lock.newCondition();
		private final Condition notEmpty = lock.newCondition();

		private Object[] items;
		private int putptr, takeptr, storage;

		public BoundedBuffer(int storage) {
			items = new Object[storage];
			this.storage = putptr = takeptr = 0;
		}

		/**
		 * @see Condition#signal()
		 * 
		 * {@link Lock#lock()} {@link Lock#unlock()}
		 * 
		 */
		public void put(E x) throws InterruptedException {
			lock.lock();
			try {
				isFull(); // buffer pieno, attesa

				items[putptr] = x; // inserisce un elemento

				nextPutIndex(); // avanza di una posizione il prossimo inserimento, diminuisce lo spazio di
								// storage

				notEmpty.signal();
			} finally {
				lock.unlock();
			}
		}

		/**
		 * @see Condition#await()
		 * 
		 */
		private void isFull() throws InterruptedException {
			while (storage == items.length)
				notFull.await();
		}

		private void nextPutIndex() {
			if (++putptr == items.length)
				putptr = 0;
			++storage;
		}

		public E take() throws InterruptedException {
			lock.lock();
			try {
				isEmpty(); // buffer vuoto, attesa

				E x = (E) items[takeptr]; // estrae un elemento

				nextTakeIndex(); // avanza di una posizione la prossima estrazione, aumenta lo spazio di storage

				notFull.signal();
				return x;
			} finally {
				lock.unlock();
			}
		}

		private void isEmpty() throws InterruptedException {
			while (storage == 0)
				notEmpty.await();
		}

		private void nextTakeIndex() {
			if (++takeptr == items.length)
				takeptr = 0;
			--storage;
		}
	}

	private static class UniTest<E> {
		private static final int N_THREAD = 10;
		private static final int STORAGE_BUFFER = 2000;
		private static final long SHUTDOWN_MILLI_SECOND = 20000;

		private final Random random = new Random();
		private final SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss");

		public void simulateCondition(BoundedBuffer<String> boundedBuff, int nThread) throws InterruptedException {
			Thread[] challenge = new Thread[nThread];

			for (int i = 0; i < nThread; ++i) {

				Thread player = new Thread(() -> {
					try {
						if (random.nextInt() % 2 == 0)
							log("Take", Thread.currentThread().getName(), boundedBuff.take());
						else {
							boundedBuff.put(Thread.currentThread().getName());
							log("Put", Thread.currentThread().getName(), Thread.currentThread().getName());
						}

					} catch (InterruptedException ie) {
						System.out.println(Thread.currentThread().getName() + " was Interrupted !!");
					}
				});

				challenge[i] = player;
			}

			run(challenge);
		}

		private void run(Thread[] challenge) throws InterruptedException {
			start(challenge);

			Thread.sleep(SHUTDOWN_MILLI_SECOND);

			shutdown(challenge);
		}

		private void start(Thread[] challenge) {
			for (int i = 0; i < challenge.length; ++i)
				challenge[i].start();
		}

		private void shutdown(Thread[] challenge) {
			for (int i = 0; i < challenge.length; ++i)
				if (challenge[i].isAlive())
					challenge[i].interrupt();
		}
		
		private void log(String operation, String player, String element) {
			System.out.println(operation + " >> " + ft.format(new Date()) + " >> " + player + " >> " + element);
		}

	}

	public static void main(String args[]) throws InterruptedException {
		// Unit test - accesso condizionato a una coda di thread 		
		new UniTest<String>().simulateCondition(new BoundedBuffer<String>(UniTest.STORAGE_BUFFER), UniTest.N_THREAD);
	}
}

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: