import java.util.Random;
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 final int TOT_TICKET = 10;
	private static final int TOT_CLIENT = 15;
	private static final long SHUTDOWN_MILLI_SECOND = 2000;

	private static class UniTest {
		private final Random random = new Random();
		private final Lock lock = new ReentrantLock();

		public void simulateLock(boolean[] ticket, int totClient) throws InterruptedException {
			Thread[] buyers = new Thread[totClient];

			for (int i = 0; i < totClient; ++i) {
				int booking = random.nextInt(ticket.length);

				Thread client = new Thread(() -> {
					criticalSection(ticket, Thread.currentThread().getId(), booking);
				});

				buyers[i] = client;
			}

			run(buyers);
		}

		/**
		 * @see Lock#lock()
		 * @see Lock#unlock()
		 * 
		 */
		private void criticalSection(boolean[] ticket, long client, int booking) {
			lock.lock();
			try {
				process(ticket, client, booking);
			} finally {
				lock.unlock();
			}
		}

		private void process(boolean[] ticket, long client, int booking) {
			if (ticket[booking]) {
				ticket[booking] = false;
				System.out.println(client + " has booked the seat No  " + booking);
			} else {
				System.out.println("Sorry " + client + " ! Seat is already Booked !");
			}
		}

		public void simulateTryLock(boolean[] ticket, int totClient) throws InterruptedException {
			Thread[] buyers = new Thread[totClient];

			for (int i = 0; i < totClient; ++i) {
				int booking = random.nextInt(ticket.length);

				Thread client = new Thread(() -> {
					tryLock(ticket, Thread.currentThread().getId(), booking);
				});

				buyers[i] = client;
			}

			run(buyers);
		}

		/**
		 * @see Lock#tryLock()
		 * 
		 */
		private boolean tryLock(boolean[] ticket, long client, int booking) {
			if (lock.tryLock()) {
				try {
					process(ticket, client, booking);
				} finally {
					lock.unlock();
				}

				return true;
			} else {
				System.out.println(client + " !! Someone else is booking !");
			}

			return false;
		}

		public void simulateLockInterruptibly(boolean[] ticket, int totClient) throws InterruptedException {
			Thread[] buyers = new Thread[totClient];

			for (int i = 0; i < totClient; ++i) {
				int booking = random.nextInt(ticket.length);
				boolean interruptibly = (i==5);

				Thread client = new Thread(() -> {
					if (interruptibly)
						System.out.println( Thread.currentThread().getId() + " is interrumpable");
					
					lockInterruptibly(ticket, Thread.currentThread().getId(), booking, interruptibly);
				});

				buyers[i] = client;
			}

			run(buyers);
		}

		/**
		 * @see Lock#lockInterruptibly()
		 * 
		 */
		private void lockInterruptibly(boolean[] ticket, long client, int booking, boolean interruptibly) {
			try {
				if (!tryLock(ticket, client, booking) && interruptibly) {

					System.out.println(client + " is trying to acquire the lock !!");
					lock.lockInterruptibly();
					System.out.println(client + " has acquired the Lock.");

					process(ticket, client, booking);
				}
			} catch (InterruptedException e) {
				System.out.println(client + " was Interrupted !!");
			} finally {
				lock.unlock();
			}
		}

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

			Thread.sleep(SHUTDOWN_MILLI_SECOND);

			shutdown(buyers);
		}

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

		private void shutdown(Thread[] buyers) {
			for (int i = 0; i < buyers.length; ++i)
				if (buyers[i].isAlive())
					buyers[i].interrupt();
		}
	}

	private static boolean[] createResourceShared(int total) throws InterruptedException {
		boolean[] ticket = new boolean[total];
		for (int i = 0; i < total; ++i)
			ticket[i] = true;

		return ticket;
	}

	public static void main(String args[]) throws InterruptedException {
		// Unit test - acceso a una sezione critica tramite interfaccia lock
		new UniTest().simulateLock(createResourceShared(TOT_TICKET), TOT_CLIENT);

		// Unit test - la sezione critica viene acquisita solo se il lock è disponibile
		// new UniTest().simulateTryLock(createResourceShared(TOT_TICKET), TOT_CLIENT);

		// Unit test - il thread tenta di interrompere il detentore del lock
		// new UniTest().simulateLockInterruptibly(createResourceShared(TOT_TICKET), TOT_CLIENT);
	}
}

Embed on website

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