Design a reusable merge sorter that can process independent halves concurrently without creating an unbounded number of threads.
Implement the ParallelMergeSorter class:
ParallelMergeSorter(maxThreads) creates a sorter that may use at most maxThreads participating threads, including the thread that calls sort.sort(values, onMerge) sorts values in nondecreasing order in place and returns only after the entire array is sorted.Use merge sort: recursively divide each range into two halves, sort both halves, and merge them. When worker capacity is available, the two halves may be processed concurrently. When no capacity is available, continue sequentially in the current thread instead of waiting for another worker slot.
Call onMerge exactly once immediately before every merge operation. Because an array of length n requires n - 1 merges, a successful call must invoke it exactly max(0, n - 1) times. Merge callbacks for disjoint ranges may overlap when maxThreads > 1, but no more than maxThreads callbacks may be active simultaneously.
The callback is an observation hook used by the judge to verify real parallel progress and the worker limit. It returns normally and does not access or modify values.
The same sorter may be used for multiple completed calls, but the judge does not call sort concurrently on the same instance. Different sorter instances must be independent.
The judge supplies the arrays and callbacks. Standard concurrency, callback, collection, lock, and thread APIs are preloaded, so you do not need import, include, package, or using statements.
Input:
Output:
Explanation: Four elements form four one-element ranges. Combining them into one sorted range requires three merge operations.
Input:
Output:
Explanation: Duplicate and negative values are preserved. At most two participating threads may execute merge callbacks at once.
1 <= maxThreads <= 80 <= values.length <= 100000-10^9 <= values[i] <= 10^9onMerge returns normally and does not access values.sort concurrently on the same sorter instance.Input
maxThreads = 4 values = [5, 2, 3, 1]
Output
values = [1, 2, 3, 5] onMerge calls = 3
Run is a quick check against the first couple of scenarios, which is roughly what these examples describe. Submit puts your class under the full set, which stays hidden.

