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

Jexl @parallel注解使用示例求助:并行执行未生效

Using JEXL's @parallel Annotation: Working Examples & Troubleshooting

Got it, let's dive into how to use JEXL's @parallel annotation properly—since the official docs are pretty light on examples, I'll walk you through working code snippets and explain why your attempts might have been running serially.

Basic Parallel Execution Example

First, let's start with a simple scenario: running multiple independent slow tasks in parallel. We'll use a utility class with simulated long-running methods, then call them via a JEXL script.

Step 1: Create a Thread-Safe Utility Class

Make sure any objects you use in parallel are thread-safe (since JEXL will execute the block across multiple threads):

public class SlowTasks {
    public long simulateDelay() {
        try {
            // Simulate 1 second of work
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return System.currentTimeMillis();
    }
}

Step 2: Write the JEXL Script with @parallel

Wrap your independent operations in an @parallel block. These operations will run concurrently instead of sequentially:

// Inject our utility class instance into the context
@parallel {
    task1End = slowTasks.simulateDelay();
    task2End = slowTasks.simulateDelay();
    task3End = slowTasks.simulateDelay();
}

// Output completion times to verify parallel execution
"Task 1 finished at: " + task1End + "\n" +
"Task 2 finished at: " + task2End + "\n" +
"Task 3 finished at: " + task3End

Step 3: Execute the Script in Java

Set up the JEXL engine, inject the utility class, and run the script:

import org.apache.commons.jexl3.*;

public class JexlParallelDemo {
    public static void main(String[] args) {
        // Initialize JEXL engine
        JexlEngine jexl = new JexlBuilder().create();
        
        // Create context and add our utility class
        JexlContext context = new MapContext();
        context.set("slowTasks", new SlowTasks());
        
        // Load and execute the script
        String scriptContent = "@parallel { task1End = slowTasks.simulateDelay(); task2End = slowTasks.simulateDelay(); task3End = slowTasks.simulateDelay(); } \"Task 1 finished at: \" + task1End + \"\\n\" + \"Task 2 finished at: \" + task2End + \"\\n\" + \"Task 3 finished at: \" + task3End";
        JexlScript script = jexl.createScript(scriptContent);
        
        Object result = script.execute(context);
        System.out.println(result);
    }
}

What to Expect

Without @parallel, this would take ~3 seconds (1s per task, sequential). With @parallel, it should finish in ~1 second—all three tasks run at the same time.

Common Pitfalls (Why Your Code Might Be Running Serially)

  1. Version Compatibility: The @parallel annotation was introduced in JEXL 3.1+. Make sure your dependency is up-to-date:

    <!-- Maven dependency example -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-jexl3</artifactId>
        <version>3.3</version> <!-- Use the latest stable release -->
    </dependency>
    
  2. Variable Dependencies: If operations in your @parallel block depend on each other, JEXL will automatically run them sequentially to preserve correctness. For example:

    @parallel {
        a = 5 + 10;
        b = a * 2; // Depends on 'a'—this will run after 'a' is computed
    }
    

    Only independent operations (no shared variables between them) will be parallelized.

  3. Non-Thread-Safe Context: If your JEXL context contains mutable, non-thread-safe objects, parallel execution can cause race conditions. Always ensure objects injected into the context are thread-safe or don't share mutable state across tasks.

Advanced Example: Parallel Collection Processing

You can also use @parallel with JEXL's foreach to process collection elements concurrently:

// Process a list of numbers to calculate their squares in parallel
numbers = [1, 2, 3, 4, 5];
@parallel {
    squaredNumbers = numbers.foreach(n -> n * n);
}

// Output the result
"Squared numbers: " + squaredNumbers

This will process each element in the list at the same time, which is much faster for large datasets.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:12:46