Java ReentrantLock control access to LinkedHashMap
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<Thread>(); Lock inventoryLock = new ReentrantLock(); final Map<String, Integer> inventoryMap = new LinkedHashMap<String, Integer>(); List<CustomerOrder> customerOrders = new ArrayList<CustomerOrder>(); Random random = new Random(); public static void main(String[] args) throws InterruptedException { Main recipe = new Main(); recipe.start();// w w w . j a v a 2s .c o m } private void start() throws InterruptedException { for (int i = 0; i < 100; i++) { inventoryMap.put("Apress Book #" + i, 1000); } for (int i = 0; i < 20; i++) { createOrderingThread(); } Thread.sleep(1100); checkInventoryLevels(); Thread.sleep(1000); for (Thread thread : orderingThreads) { thread.interrupt(); } Thread.sleep(1000); checkInventoryLevels(); displayOrders(); } private void displayOrders() { try { inventoryLock.lock(); for (CustomerOrder order : customerOrders) { System.out.println( order.getQuantityOrdered() + " " + order.getItemOrdered() + " for " + order.getCustomerName()); } } finally { inventoryLock.unlock(); } } private void createOrderingThread() { Thread orderingThread = new Thread(new Runnable() { public void run() { 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, quantityOrdered, customerName); customerOrders.add(order); System.out .println("Order fulfilled for " + customerName + " of " + itemOrdered + " (" + quantityOrdered + ")"); return true; } finally { inventoryLock.unlock(); } } private void checkInventoryLevels() { try { inventoryLock.lock(); for (Map.Entry<String, Integer> inventoryEntry : inventoryMap.entrySet()) { System.out.println("Inventory Level :" + inventoryEntry.getKey() + " " + inventoryEntry.getValue()); } } finally { inventoryLock.unlock(); } } } class CustomerOrder { String itemOrdered; int quantityOrdered; String customerName; CustomerOrder(String itemOrdered, int quantityOrdered, String customerName) { this.itemOrdered = itemOrdered; this.quantityOrdered = quantityOrdered; this.customerName = customerName; } public String getItemOrdered() { return itemOrdered; } public int getQuantityOrdered() { return quantityOrdered; } public String getCustomerName() { return customerName; } }