Java 17 Recipes
-5. Coordinating Different Collections
Download 3.2 Mb. Pdf ko'rish
|
Java 17 Recipes
10-5. Coordinating Different Collections
Problem You need to modify different but related collections at the same time, and you want to ensure that no other threads can see these modifications until they have been completed. Solution 1 By synchronizing on the principal collection, you can guarantee that collection can be updated simultaneously. In the following example, the fulfillOrder method needs to check the inventory of the order to be fulfilled. If there is enough inventory to fulfill the order, it needs to add the order to the customerOrders list. The fulfillOrder() method synchronizes on the inventoryMap map and modifies both the inventoryMap and the customerOrders list before finishing the synchronized block. Set public static void main(String[] args) throws InterruptedException { Recipe10_5_1 recipe = new Recipe10_5_1(); recipe.start(); } final Map List Random random = new Random(); private void start() throws InterruptedException { loadLoggingConfiguration(); // let's populate our inventory with items. // at most, we have 20 books for (int i =0;i < 100;i++) { inventoryMap.put("Apress Book #"+i,100); } // now, let's create ordering threads. for (int i= 0;i < 20;i++) { createOrderingThread(); } Chapter 10 ConCurrenCy 365 //wait a little Thread.sleep(100); // Check on inventory right now checkInventoryLevels(); // Wait little longer Thread.sleep(100); orderingThreads.stream().forEach((thread) -> { thread.interrupt(); }); Thread.sleep(1000); // Check inventory levels again checkInventoryLevels(); // Print the orders. displayOrders(); } Logger logger = Logger.getLogger("recipeLogger"); private void createOrderingThread() { Thread orderingThread = new Thread(() -> { while (!Thread.interrupted()) { createRandomOrder(); } }); orderingThread.start(); orderingThreads.add(orderingThread); } private void createRandomOrder() { String itemOrdered = "Apress Book #"+random.nextInt(100); int quantityOrdered = random.nextInt(2)+1; String customerName = "Customer :"+UUID.randomUUID().toString(); fulfillOrder(itemOrdered, quantityOrdered, customerName); } Chapter 10 ConCurrenCy 366 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; } } private boolean fulfillOrder(String itemOrdered, int quantityOrdered, String customerName) { synchronized (inventoryMap) { int currentInventory = 0; if (inventoryMap != null) { 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 } Chapter 10 ConCurrenCy 367 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; } } private void checkInventoryLevels() { synchronized (inventoryMap) { System.out.println("------------------------------------"); inventoryMap.entrySet().stream().forEach((inventoryEntry) -> { System.out.println("Inventory Level :"+inventoryEntry .getKey()+" "+inventoryEntry.getValue()); }); System.out.println("------------------------------------"); } } private void displayOrders() { synchronized (inventoryMap) { customerOrders.stream().forEach((order) -> { System.out.println(order.getQuantityOrdered()+" "+order.getItemOrdered()+" for "+order.getCustomerName()); }); } } The output is similar to: ------------------------------------ Inventory Level :Apress Book #0 100 Inventory Level :Apress Book #1 100 Inventory Level :Apress Book #2 100 Inventory Level :Apress Book #3 100 Inventory Level :Apress Book #4 100 Chapter 10 ConCurrenCy 368 Inventory Level :Apress Book #5 100 Inventory Level :Apress Book #6 100 Inventory Level :Apress Book #7 100 Inventory Level :Apress Book #8 100 Inventory Level :Apress Book #9 100 Inventory Level :Apress Book #10 100 Inventory Level :Apress Book #11 100 Inventory Level :Apress Book #12 100 Inventory Level :Apress Book #13 100 Inventory Level :Apress Book #14 100 Inventory Level :Apress Book #15 100 ... ------------------------------------ Order fulfilled for Customer :70a697d1-08d2-4ad7-b00c-17558930e0ab of Apress Book #64 (2) Order fulfilled for Customer :4db86e58-a895-4992-9090-84a52f9314f6 of Apress Book #44 (2) Order fulfilled for Customer :cc278024-0630-424f-99bb-091d4bb73d25 of Apress Book #20 (1) Order fulfilled for Customer :f43f9edd-17f3-403c-b3b6-b91521b9f970 of Apress Book #24 (1) Order fulfilled for Customer :a1c94246-3671-4373-bbbb-968d32fca100 of Apress Book #53 (2) Order fulfilled for Customer :110382cf-79ff-4042-9ad4-bb4316764281 of Apress Book #31 (2) Order fulfilled for Customer :e3255a74-dfdc-4ef4-b388-02745249c0a9 of Apress Book #38 (1) Order fulfilled for Customer :fd2fa1fd-b9b8-4bca-92a8-6023a1fbde3e of Apress Book #40 (2) Order fulfilled for Customer :5cead5b3-70bf-4f98-82c4-5ee34e90f02d of Apress Book #53 (2) Order fulfilled for Customer :c0e0b2d3-4d58-41ef-9127-8e3d5665d976 of Apress Book #38 (1) Order fulfilled for Customer :38f5ea73-d22b-4714-a319-7599d30a1b9a of Apress Book #86 (1) ... Chapter 10 ConCurrenCy |
Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling
ma'muriyatiga murojaat qiling