Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • How to Implement Java Concurrency Code

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 472
    Answer it

    Java!!

    Concurrency Code

     

    You have been given a simple API to buy and print postage. Write a program that submits each incoming order to the API and then prints the shipping label.

     

    Unfortunately each call to the shipping label API is SLOW… To compensate for this, use concurrency so that your program can be making several calls to the API at one time.

     

    We also need to keep track of our expenses, so make sure to calculate how much money is being spent on shipping.

     

    Starter Code:

    1) ShippingService.java

    package shipping;
    
    import java.util.Random;
    import java.util.UUID;
    
    /**
     * Simulates an external API for buying postage
     */
    public class ShippingService {
    
        private final Random random = new Random();
        
        private static final int BASE_COST_IN_CENTS = 950;
        private static final int COST_PER_POUND_IN_CENTS = 75;
        
        private static final int MIN_TIME_TO_SLEEP = 3;
        private static final int MAX_TIME_TO_SLEEP = 5;
          
        /**
         * Purchase a shipping label
         * @param recipientName The First and Last name of the recipient
         * @param destinationAddress The full mailing address of the recipient
         * @param weightInPounds The weight of the package
         * @return A ShippingLabel with tracking information and cost
         */
        public ShippingLabel getShippingLabel(String recipientName, String destinationAddress, double weightInPounds) {
            
            // Sleep for 3-10 seconds
            Integer millis = random.ints(1, MIN_TIME_TO_SLEEP, MAX_TIME_TO_SLEEP).map(seconds -> seconds * 1_000).findFirst().getAsInt();
            try {
                Thread.sleep(millis);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            
            String confirmationNumber = UUID.randomUUID().toString().replace("-", "");
            int shippingCost = (int) (BASE_COST_IN_CENTS + COST_PER_POUND_IN_CENTS * weightInPounds);
            return new ShippingLabel(confirmationNumber, recipientName, destinationAddress, weightInPounds, shippingCost);
            
        }
        
    }
    

    2) ShippingLabel.java

     

    package shipping;
    
    import java.util.Objects;
    
    /**
     * Represents a Shipping Label to be used as postage
     */
    public class ShippingLabel {
        
        private String trackingNumber;    
        private String recipientName;
        private String destinationAddress;
        private double weightInPounds;
        private int costInCents;
    
        public ShippingLabel() {
            
        }
        
        public ShippingLabel(String trackingNumber, String recipientName,  String destinationAddress, double weightInPounds, int costInCents) {
            this.trackingNumber = trackingNumber;
            this.recipientName = recipientName;
            this.destinationAddress = destinationAddress;
            this.weightInPounds = weightInPounds;
            this.costInCents = costInCents;
        }   
        
        public String getTrackingNumber() {
            return trackingNumber;
        }
    
        public void setTrackingNumber(String trackingNumber) {
    //        this.trackingNumber = trackingNumber;
        }
    
        public String getRecipientName() {
            return recipientName;
        }
    
        public void setRecipientName(String recipientName) {
            this.recipientName = recipientName;
        }
        
        public String getDestinationAddress() {
            return destinationAddress;
        }
    
        public void setDestinationAddress(String destinationAddress) {
            this.destinationAddress = destinationAddress;
        }
    
        public double getWeightInPounds() {
            return weightInPounds;
        }
    
        public void setWeightInPounds(double weightInPounds) {
            this.weightInPounds = weightInPounds;
        }
    
        public int getCostInCents() {
            return costInCents;
        }
    
        public void setCostInCents(int costInCents) {
            this.costInCents = costInCents;
        }
    
        @Override
        public String toString() {
            return "ShippingLabel{" + "trackingNumber=" + trackingNumber + ", recipientName=" + recipientName + ", destinationAddress=" + destinationAddress + ", weightInPounds=" + weightInPounds + ", costInCents=" + costInCents + '}';
        }   
        
        @Override
        public int hashCode() {
            int hash = 3;
            hash = 97 * hash + Objects.hashCode(this.trackingNumber);
            hash = 97 * hash + Objects.hashCode(this.recipientName);
            hash = 97 * hash + Objects.hashCode(this.destinationAddress);
            hash = 97 * hash + (int) (Double.doubleToLongBits(this.weightInPounds) ^ (Double.doubleToLongBits(this.weightInPounds) >>> 32));
            hash = 97 * hash + this.costInCents;
            return hash;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final ShippingLabel other = (ShippingLabel) obj;
            if (Double.doubleToLongBits(this.weightInPounds) != Double.doubleToLongBits(other.weightInPounds)) {
                return false;
            }
            if (this.costInCents != other.costInCents) {
                return false;
            }
            if (!Objects.equals(this.trackingNumber, other.trackingNumber)) {
                return false;
            }
            if (!Objects.equals(this.recipientName, other.recipientName)) {
                return false;
            }
            if (!Objects.equals(this.destinationAddress, other.destinationAddress)) {
                return false;
            }
            return true;
        }    
        
    }
    

     

    Details:

    The attached code simulates an API that generates shipping labels. Include it with your code.

    1) Create an "Order" class to represent an incoming order with the following fields

    a. Customer Name

    b. Customer Address

    c. Pounds of Chocolate

     

    2) Create a list to hold incoming orders and populate it with at least 6 orders

    3) Create an ExecutorService instance to manage threads

    4) Write a Runnable class to process each order by calling the API to generate a shipping label

     

    a) "Print" each label by printing it to the console

       i. Although ShippingLabel does have a toString() method, it is not very readable. Print the shipping label in a more user-friendly way.

       ii. Watch out for concurrency problems!

     

    b) Keep track of the total cost of all shipments

       i. There are many ways to do this - use any mechanism you like, but make sure that you account for any possible race conditions

     

    5) Cleanly shutdown the ExecutorService

    6) Print the total cost after all orders have been filled

 0 Answer(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: