Knowledge Guide
HomeConcurrencyConcurrency Problems

Problem 11 Palindrome Multithreaded Investigator

Overview

The challenge at hand is to evaluate a sequence of numbers and categorize them into palindromes and non-palindromes. A palindrome is a number (or a word) that reads the same backward as forward (e.g., 121, 12321).

In this problem, the task of categorization is done by two separate threads:

The challenge is magnified by the constraint that the numbers should be output in sequence, regardless of their categorization. This implies the need for synchronization between the threads to maintain the sequence of the input while processing in parallel.

Concurrency Introduction

Concurrency introduces the concept of executing multiple sequences of instructions in overlapping time periods. In this problem, we're using two threads to evaluate a series of numbers in parallel, which will require synchronization to ensure that the output is consistent with the sequence of the input.

Threading can optimize performance, especially when tasks can be run independently. However, when threads need to access shared data (like our list of numbers), synchronization becomes essential. Synchronization ensures that threads don't interfere with each other and the results remain consistent.

Pseudocode

Initialize an array of numbers, currentIndex to 0, and other synchronization primitives Function IsPalindrome(number): Convert number to string Return true if string is the same when reversed, else false ThreadFunction DetectPalindromes: While currentIndex is less than array length: Acquire lock: If number at currentIndex is a palindrome: Output number as palindrome Increment currentIndex Signal non-palindrome thread and wait for the palindrome thread ThreadFunction DetectNonPalindromes: While currentIndex is less than array length: Acquire lock: If number at currentIndex is not a palindrome: Output number as non-palindrome Increment currentIndex Signal palindrome thread and wait for the non-palindrome thread Main: Start both threads Wait for both threads to finish

This pseudocode gives an abstract view of how the problem will be approached. The "lock" ensures that at any given time, only one thread evaluates and outputs a number. The "signals" and "waits" are synchronization primitives to control the order of execution and ensure numbers are processed in sequence.

Algorithm Walkthrough

Let's walk through a simple example with an array of numbers [123, 121, 3223, 4554, 1234].

Initialization:

Thread A (Palindrome Detector):

Thread B (Non-Palindrome Detector):

Thread A:

Thread B:

Thread A:

Thread B:

Since there are no more numbers to check (currentIndex is now equal to the length of the array), both threads can terminate.

In this setup, only one thread operates on the array at any given time, controlled by the signaling mechanism. The signaling ensures that the two threads take turns in a controlled manner, and the currentIndex variable makes sure they are always looking at the correct position in the array.

Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
java
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Solution {

  private static final int MAX_NUM = 10;
  private static final List<Integer> numbers = new ArrayList<>(
    List.of(
      1211,
      12345,
      13331,
      45654,
      45454,
      78987,
      111111,
      112211,
      909909,
      919919
    )
  );
  private int currentIndex = 0;
  private final Lock lock = new ReentrantLock();
  private final Condition cond = lock.newCondition();

  // Method to check if a number is a palindrome
  private static boolean isPalindrome(int n) {
    String s = Integer.toString(n);
    String rev = new StringBuilder(s).reverse().toString();
    return s.equals(rev);
  }

  // Method for detecting palindromes
  public void detectPalindromes() {
    while (true) {
      lock.lock();
      try {
        if (currentIndex >= MAX_NUM) {
          break;
        }

        if (isPalindrome(numbers.get(currentIndex))) {
          System.out.println(numbers.get(currentIndex) + " is a palindrome.");
          currentIndex++;
          cond.signalAll(); // Notify all threads
        } else {
          cond.await(); // Wait for the condition
        }
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        e.printStackTrace();
      } finally {
        lock.unlock();
      }
    }
  }

  // Method for detecting non-palindromes
  public void detectNotPalindromes() {
    while (true) {
      lock.lock();
      try {
        if (currentIndex >= MAX_NUM) {
          break;
        }

        if (!isPalindrome(numbers.get(currentIndex))) {
          System.out.println(
            numbers.get(currentIndex) + " is not a palindrome."
          );
          currentIndex++;
          cond.signalAll(); // Notify all threads
        } else {
          cond.await(); // Wait for the condition
        }
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        e.printStackTrace();
      } finally {
        lock.unlock();
      }
    }
  }

  public static void main(String[] args) {
    Solution detector = new Solution();

    // Creating threads for palindrome and non-palindrome tasks
    Thread threadA = new Thread(detector::detectPalindromes);
    Thread threadB = new Thread(detector::detectNotPalindromes);

    // Starting threads
    threadA.start();
    threadB.start();
  }
}
🤖 Don't fully get this? Learn it with Claude

Stuck on Problem 11 Palindrome Multithreaded Investigator? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🪜 Hint ladder (no spoilers)

Progressively stronger hints — you still solve it.

I'm working on the problem **Problem 11 Palindrome Multithreaded Investigator** (Concurrency). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🎨 Explain the approach visually

See the technique, not just code.

Explain the optimal approach to **Problem 11 Palindrome Multithreaded Investigator** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔍 Review my solution

Catch bugs, edge cases, sub-optimality.

I'll paste my solution to **Problem 11 Palindrome Multithreaded Investigator**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔁 Drill the pattern

Lock in recognition with look-alikes.

Give me 2 problems that use the SAME underlying pattern as **Problem 11 Palindrome Multithreaded Investigator**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes