Katkat

Review concurrent code quality

J.P. MorganSoftware Engineer · Technical Screen

Last updated

This question tests your ability to identify thread-safety issues, improper synchronization, and architectural code smells within a multi-threaded data processing class.

The Scenario

You are performing a code review for a junior developer on a class designed to process incoming financial market data updates. The class is intended to track the 'latest price' for a specific ticker symbol while maintaining a processing count.

Review the provided Java snippet and identify at least three critical issues related to concurrency, thread safety, and software design. After identifying the flaws, provide a refactored version of the class that is thread-safe and follows cleaner design principles.

public class PriceProcessor {
    private volatile double latestPrice;
    private int updateCount = 0;
    private String ticker = "AAPL";

    public void onUpdate(double newPrice) {
        latestPrice = newPrice;
        updateCount++;
        System.out.println("Updated " + ticker + " to " + latestPrice);
    }

    public double getLatestPrice() {
        return latestPrice;
    }

    public int getUpdateCount() {
        return updateCount;
    }
}

Requirements

  1. Explain why volatile is insufficient for the updateCount field.
  2. Explain the atomicity problem present in the onUpdate method.
  3. Identify design flaws regarding configuration and the Single Responsibility Principle.
  4. Provide a corrected, thread-safe implementation using java.util.concurrent utilities where appropriate.

Hints

Hint 1

Consider whether a volatile variable guarantees atomicity for read-modify-write operations like incrementing a counter.

Hint 2

Think about how multiple threads calling onUpdate simultaneously could lead to lost updates or inconsistent state between the price and the count.

Hint 3

Consider moving the hard-coded ticker symbol to a constructor parameter to improve testability and flexibility.

Follow-up questions

  • How would your implementation change if the 'onUpdate' method needed to perform a heavy calculation before updating the price?
  • If we needed to ensure that 'getLatestPrice' and 'getUpdateCount' are always returned as a consistent snapshot, how would you modify the synchronization strategy?
  • What are the performance implications of using a 'synchronized' keyword versus using 'Atomic' classes like 'AtomicInteger' or 'ReentrantReadWriteLock'?