Java examples for Thread:Lock
Using a reentrant lock to prevent multiple threads from accessing the same code
import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.UUID; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Main { Set<Thread> orderingThreads = new HashSet<>(); Lock inventoryLock = new ReentrantLock(); public static void main(String[] args) throws InterruptedException { Main recipe = new Main(); recipe.start();// ww w . j a v a2 s. c om } final Map<String, Integer> inventoryMap = new LinkedHashMap<>(); List<CustomerOrder> customerOrders = new ArrayList<>(); Random random = new Random(); private void start() throws InterruptedException { for (int i = 0; i < 100; i++) { inventoryMap.put("Book #" + i, 1000); } for (int i = 0; i < 20; i++) { createOrderingThread(); } Thread.sleep(100); checkInventoryLevels(); Thread.sleep(100); orderingThreads.stream().forEach((thread) -> { thread.interrupt(); }); Thread.sleep(1000); checkInventoryLevels(); displayOrders(); } private void displayOrders() { try { inventoryLock.lock(); customerOrders.stream().forEach( (order) -> { System.out.println(order.getItemOrdered()); }); } finally { inventoryLock.unlock(); } } private void createOrderingThread() { Thread orderingThread = new Thread(() -> { while (!Thread.interrupted()) { createRandomOrder(); } }); orderingThread.start(); orderingThreads.add(orderingThread); } private void createRandomOrder() { String itemOrdered = "Book #" + random.nextInt(100); int quantityOrdered = random.nextInt(2) + 1; String customerName = "Customer :" + UUID.randomUUID().toString(); fulfillOrder(itemOrdered, quantityOrdered, customerName); } private boolean fulfillOrder(String itemOrdered, int quantityOrdered, String customerName) { try { inventoryLock.lock(); int currentInventory = inventoryMap.get(itemOrdered); if (currentInventory < quantityOrdered) { System.out.println("Couldn't fulfill order for " + customerName + " not enough " + itemOrdered + " (" + quantityOrdered + ")"); return false; // sorry, we sold out } inventoryMap.put(itemOrdered, currentInventory - quantityOrdered); CustomerOrder order = new CustomerOrder(itemOrdered); customerOrders.add(order); System.out.println("Order fulfilled for " + customerName + " of " + itemOrdered + " (" + quantityOrdered + ")"); return true; } finally { inventoryLock.unlock(); } } private void checkInventoryLevels() { try { inventoryLock.lock(); inventoryMap .entrySet() .stream() .forEach( (inventoryEntry) -> { System.out.println("Inventory Level :" + inventoryEntry.getKey() + " " + inventoryEntry.getValue()); }); } finally { inventoryLock.unlock(); } } } class CustomerOrder { String itemOrdered; CustomerOrder(String itemOrdered) { this.itemOrdered = itemOrdered; } public String getItemOrdered() { return itemOrdered; } }