You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将RecursiveTask结果转换为ConcurrentMap?自定义SearchTask2实现问询

Implementing RecursiveTask<Map<Short, Long>> and Converting Results to ConcurrentMap

Hey there! Let's work through your SearchTask2 implementation and the ConcurrentMap conversion requirement. Here's a complete, practical solution tailored to your code snippet:

1. Complete SearchTask2 Implementation

First, let's finish the SearchTask2 class. The core of any RecursiveTask is the compute() method—this is where we split large tasks into smaller chunks (when above your threshold) and merge results from sub-tasks.

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.RecursiveTask;

public class SearchTask2 extends RecursiveTask<Map<Short, Long>> {
    private final int majorDataThreshold = 16000;
    private final ConcurrentNavigableMap<Short, Long> dataMap;
    private final long fromRange;
    private final long toRange;
    private final boolean fromInclusive;
    private final boolean toInclusive;

    // Constructor: Convert input Map to ConcurrentNavigableMap for safe parallel processing
    public SearchTask2(final Map<Short, Long> dataSource, final long fromRange, final long toRange,
                       final boolean fromInclusive, final boolean toInclusive) {
        // Use ConcurrentSkipListMap for navigable features; swap to ConcurrentHashMap if you don't need ordering
        this.dataMap = new ConcurrentSkipListMap<>(dataSource);
        this.fromRange = fromRange;
        this.toRange = toRange;
        this.fromInclusive = fromInclusive;
        this.toInclusive = toInclusive;
    }

    @Override
    protected Map<Short, Long> compute() {
        // Calculate the size of the current range (adjust logic to match your actual range definition)
        long rangeSize = toRange - fromRange + (fromInclusive && toInclusive ? 1 : 0);

        // If range is small enough, process directly without splitting
        if (rangeSize <= majorDataThreshold) {
            ConcurrentMap<Short, Long> result = new ConcurrentHashMap<>();
            // Filter entries that fall within the target range
            for (Map.Entry<Short, Long> entry : dataMap.entrySet()) {
                long value = entry.getValue();
                boolean isInRange = false;
                
                // Handle inclusive/exclusive bounds logic
                if (fromInclusive && toInclusive) {
                    isInRange = value >= fromRange && value <= toRange;
                } else if (fromInclusive) {
                    isInRange = value >= fromRange && value < toRange;
                } else if (toInclusive) {
                    isInRange = value > fromRange && value <= toRange;
                } else {
                    isInRange = value > fromRange && value < toRange;
                }

                if (isInRange) {
                    result.put(entry.getKey(), entry.getValue());
                }
            }
            return result;
        }

        // Split the range into two sub-tasks for parallel processing
        long midRange = fromRange + (rangeSize / 2);
        SearchTask2 leftTask = new SearchTask2(dataMap, fromRange, midRange, fromInclusive, false);
        SearchTask2 rightTask = new SearchTask2(dataMap, midRange, toRange, true, toInclusive);

        // Fork the left task to run asynchronously
        leftTask.fork();
        // Compute the right task synchronously, then wait for the left task's result
        Map<Short, Long> rightResult = rightTask.compute();
        Map<Short, Long> leftResult = leftTask.join();

        // Merge results into a ConcurrentMap to ensure thread safety during merging
        ConcurrentMap<Short, Long> mergedResult = new ConcurrentHashMap<>(rightResult);
        mergedResult.putAll(leftResult);

        return mergedResult;
    }
}

2. Converting RecursiveTask Results to ConcurrentMap

There are two clean, efficient ways to handle this:

Modify the task's return type to ConcurrentMap<Short, Long> instead of Map—this eliminates the need for post-conversion entirely, which is the most performant approach:

public class SearchTask2 extends RecursiveTask<ConcurrentMap<Short, Long>> {
    // ... rest of the code remains nearly identical; just return ConcurrentMap instances in compute()
}

Option 2: Convert After Task Completion

If you need to keep the Map return type, convert the result once the task finishes executing:

// Execute the task
SearchTask2 task = new SearchTask2(yourDataSource, 0L, 100000L, true, true);
Map<Short, Long> resultMap = task.invoke();

// Convert to ConcurrentHashMap
ConcurrentMap<Short, Long> concurrentResult = new ConcurrentHashMap<>(resultMap);

// Or to ConcurrentSkipListMap if you need navigable/ordered features
ConcurrentNavigableMap<Short, Long> navigableConcurrentResult = new ConcurrentSkipListMap<>(resultMap);

Key Notes

  • Thread Safety: Using ConcurrentMap for intermediate and final results ensures safe merging of sub-task outputs—critical for reliable parallel processing.
  • Threshold Tuning: Adjust majorDataThreshold based on performance testing. Too small and you'll get excessive task overhead; too large and you won't leverage parallelism effectively.
  • Range Logic: Double-check the range filtering logic in compute() to match your exact inclusive/exclusive bound requirements.

内容的提问来源于stack exchange,提问作者edwin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:38:49