CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-springframework--spring-core

Spring Framework Core - IoC Container and Dependency Injection

Pending
Overview
Eval results
Files

task-execution.mddocs/

Task Execution

Spring Core provides a comprehensive task execution framework that abstracts thread management and provides both synchronous and asynchronous task execution capabilities. This system supports everything from simple thread pools to modern virtual thread implementations.

Core Task Executor Interfaces

The task execution system is built around a hierarchy of interfaces that provide increasingly sophisticated execution capabilities.

TaskExecutor Interface

@FunctionalInterface
public interface TaskExecutor extends Executor {
    void execute(Runnable task);
}

public interface AsyncTaskExecutor extends TaskExecutor {
    long TIMEOUT_UNLIMITED = Long.MAX_VALUE;
    long TIMEOUT_IMMEDIATE = 0;
    
    void execute(Runnable task, long startTimeout);
    Future<?> submit(Runnable task);
    <T> Future<T> submit(Callable<T> task);
}

public interface SchedulingTaskExecutor extends AsyncTaskExecutor {
    boolean prefersShortLivedTasks();
}

Task Decorator Interface

@FunctionalInterface
public interface TaskDecorator {
    Runnable decorate(Runnable runnable);
}

Usage Examples

// Basic task execution
TaskExecutor executor = new SimpleAsyncTaskExecutor();

// Execute fire-and-forget tasks
executor.execute(() -> {
    System.out.println("Task executed in: " + Thread.currentThread().getName());
});

// Asynchronous execution with results
AsyncTaskExecutor asyncExecutor = new SimpleAsyncTaskExecutor();

// Submit runnable task
Future<?> future1 = asyncExecutor.submit(() -> {
    // Long running task
    processLargeDataset();
});

// Submit callable task
Future<String> future2 = asyncExecutor.submit(() -> {
    return fetchDataFromRemoteService();
});

// Wait for results
try {
    future1.get(5, TimeUnit.SECONDS);
    String result = future2.get(10, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
    // Handle timeout
}

// Task decoration
TaskDecorator decorator = task -> {
    return () -> {
        String originalName = Thread.currentThread().getName();
        Thread.currentThread().setName("CustomTask-" + originalName);
        try {
            task.run();
        } finally {
            Thread.currentThread().setName(originalName);
        }
    };
};

// Apply decorator to executor (implementation-dependent)

Task Executor Implementations

Spring provides several built-in task executor implementations for different use cases.

SimpleAsyncTaskExecutor

public class SimpleAsyncTaskExecutor extends CustomizableThreadCreator 
    implements AsyncTaskExecutor, Serializable {
    
    public static final int UNBOUNDED_CONCURRENCY = -1;
    public static final int NO_CONCURRENCY = 0;
    
    public SimpleAsyncTaskExecutor();
    public SimpleAsyncTaskExecutor(String threadNamePrefix);
    public SimpleAsyncTaskExecutor(ThreadFactory threadFactory);
    
    public void setConcurrencyLimit(int concurrencyLimit);
    public int getConcurrencyLimit();
    public boolean isThrottleActive();
    
    public void setTaskDecorator(TaskDecorator taskDecorator);
    
    @Override
    public void execute(Runnable task);
    @Override
    public void execute(Runnable task, long startTimeout);
    @Override
    public Future<?> submit(Runnable task);
    @Override
    public <T> Future<T> submit(Callable<T> task);
    
    protected void doExecute(Runnable task);
    protected Thread createThread(Runnable runnable);
}

SyncTaskExecutor

public class SyncTaskExecutor implements TaskExecutor, Serializable {
    @Override
    public void execute(Runnable task);
}

VirtualThreadTaskExecutor (Java 21+)

public class VirtualThreadTaskExecutor implements AsyncTaskExecutor, Serializable {
    public VirtualThreadTaskExecutor();
    public VirtualThreadTaskExecutor(String threadNamePrefix);
    
    public void setThreadNamePrefix(String threadNamePrefix);
    public String getThreadNamePrefix();
    
    public void setTaskDecorator(TaskDecorator taskDecorator);
    public TaskDecorator getTaskDecorator();
    
    @Override
    public void execute(Runnable task);
    @Override
    public Future<?> submit(Runnable task);
    @Override
    public <T> Future<T> submit(Callable<T> task);
    
    @Override
    public void execute(Runnable task, long startTimeout);
    
    protected Thread createVirtualThread(Runnable runnable);
}

Usage Examples

// Simple async task executor with concurrency control
SimpleAsyncTaskExecutor simpleExecutor = new SimpleAsyncTaskExecutor("MyApp-");
simpleExecutor.setConcurrencyLimit(10); // Limit to 10 concurrent threads
simpleExecutor.setTaskDecorator(task -> {
    return () -> {
        long start = System.currentTimeMillis();
        try {
            task.run();
        } finally {
            long duration = System.currentTimeMillis() - start;
            System.out.println("Task completed in " + duration + "ms");
        }
    };
});

// Execute multiple tasks
for (int i = 0; i < 20; i++) {
    final int taskId = i;
    simpleExecutor.execute(() -> {
        System.out.println("Executing task " + taskId + 
                         " in thread " + Thread.currentThread().getName());
        // Simulate work
        try { Thread.sleep(1000); } catch (InterruptedException e) {}
    });
}

// Synchronous executor (for testing or single-threaded contexts)
TaskExecutor syncExecutor = new SyncTaskExecutor();
syncExecutor.execute(() -> {
    // This will execute in the calling thread
    System.out.println("Sync execution in: " + Thread.currentThread().getName());
});

// Virtual thread executor (Java 21+)
VirtualThreadTaskExecutor virtualExecutor = new VirtualThreadTaskExecutor("VirtualTask-");
virtualExecutor.setTaskDecorator(task -> () -> {
    System.out.println("Virtual thread: " + Thread.currentThread());
    task.run();
});

// Virtual threads are ideal for I/O-bound tasks
List<Future<String>> futures = new ArrayList<>();
for (int i = 0; i < 10000; i++) { // Can handle thousands of virtual threads
    Future<String> future = virtualExecutor.submit(() -> {
        // Simulate I/O operation
        Thread.sleep(Duration.ofSeconds(1));
        return "Result from virtual thread";
    });
    futures.add(future);
}

// Collect results
List<String> results = futures.stream()
    .map(future -> {
        try { return future.get(); }
        catch (Exception e) { return "Error"; }
    })
    .collect(Collectors.toList());

Thread Pool Task Executor Support

While the core module doesn't include full thread pool implementations, it provides the foundation interfaces that are used by Spring's thread pool executors in other modules.

Lifecycle Management

public interface DisposableBean {
    void destroy() throws Exception;
}

public interface InitializingBean {
    void afterPropertiesSet() throws Exception;
}

// Task executors often implement these for proper lifecycle management
public interface TaskExecutorConfiguration {
    void initialize();
    void shutdown();
    boolean awaitTermination(long timeout, TimeUnit unit);
}

Usage Examples

// Custom task executor with lifecycle management
public class ManagedTaskExecutor implements AsyncTaskExecutor, InitializingBean, DisposableBean {
    private ExecutorService executor;
    private final String threadNamePrefix;
    private TaskDecorator taskDecorator;
    
    public ManagedTaskExecutor(String threadNamePrefix) {
        this.threadNamePrefix = threadNamePrefix;
    }
    
    @Override
    public void afterPropertiesSet() {
        ThreadFactory threadFactory = new CustomizableThreadFactory(threadNamePrefix);
        this.executor = Executors.newCachedThreadPool(threadFactory);
    }
    
    @Override
    public void destroy() throws Exception {
        if (executor != null) {
            executor.shutdown();
            if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        }
    }
    
    @Override
    public void execute(Runnable task) {
        Runnable decoratedTask = (taskDecorator != null) ? taskDecorator.decorate(task) : task;
        executor.execute(decoratedTask);
    }
    
    @Override
    public Future<?> submit(Runnable task) {
        Runnable decoratedTask = (taskDecorator != null) ? taskDecorator.decorate(task) : task;
        return executor.submit(decoratedTask);
    }
    
    @Override
    public <T> Future<T> submit(Callable<T> task) {
        return executor.submit(task);
    }
    
    public void setTaskDecorator(TaskDecorator taskDecorator) {
        this.taskDecorator = taskDecorator;
    }
}

// Usage with Spring lifecycle
ManagedTaskExecutor managedExecutor = new ManagedTaskExecutor("Managed-");
managedExecutor.setTaskDecorator(task -> {
    return () -> {
        MDC.put("taskId", UUID.randomUUID().toString());
        try {
            task.run();
        } finally {
            MDC.clear();
        }
    };
});

managedExecutor.afterPropertiesSet(); // Initialize

// Use the executor
Future<String> result = managedExecutor.submit(() -> {
    // Task execution with proper logging context
    return "Task completed";
});

// Cleanup
managedExecutor.destroy();

Task Execution Utilities

CustomizableThreadCreator

public class CustomizableThreadCreator implements Serializable {
    public static final String DEFAULT_THREAD_NAME_PREFIX = 
        ClassUtils.getShortName(CustomizableThreadCreator.class) + "-";
    
    private String threadNamePrefix = DEFAULT_THREAD_NAME_PREFIX;
    private int threadPriority = Thread.NORM_PRIORITY;
    private boolean daemon = false;
    private ThreadGroup threadGroup;
    private Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
    
    public CustomizableThreadCreator();
    public CustomizableThreadCreator(String threadNamePrefix);
    
    public void setThreadNamePrefix(String threadNamePrefix);
    public String getThreadNamePrefix();
    
    public void setThreadPriority(int threadPriority);
    public int getThreadPriority();
    
    public void setDaemon(boolean daemon);
    public boolean isDaemon();
    
    public void setThreadGroupName(String name);
    public void setThreadGroup(ThreadGroup threadGroup);
    public ThreadGroup getThreadGroup();
    
    public void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler uncaughtExceptionHandler);
    public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
    
    public Thread createThread(Runnable runnable);
    protected String nextThreadName();
    public String getDefaultThreadNamePrefix();
}

Usage Examples

// Customizable thread creation
CustomizableThreadCreator threadCreator = new CustomizableThreadCreator("WorkerPool-");
threadCreator.setThreadPriority(Thread.MAX_PRIORITY);
threadCreator.setDaemon(true);
threadCreator.setUncaughtExceptionHandler((thread, ex) -> {
    System.err.println("Uncaught exception in thread " + thread.getName() + ": " + ex);
});

// Create custom threads
Thread workerThread = threadCreator.createThread(() -> {
    // Worker task implementation
    performWork();
});

workerThread.start();

// Use with task executors
public class CustomThreadTaskExecutor extends SimpleAsyncTaskExecutor {
    public CustomThreadTaskExecutor() {
        super("CustomTask-");
        setThreadPriority(Thread.HIGH_PRIORITY);
        setDaemon(false);
    }
    
    @Override
    protected Thread createThread(Runnable runnable) {
        Thread thread = super.createThread(runnable);
        thread.setUncaughtExceptionHandler((t, e) -> {
            // Custom exception handling
            handleTaskException(t, e);
        });
        return thread;
    }
    
    private void handleTaskException(Thread thread, Throwable exception) {
        // Log exception, notify monitoring system, etc.
    }
}

Asynchronous Method Support Foundation

While async method execution is handled in Spring Context, the core module provides the foundational interfaces.

Future Result Handling

// Standard JDK interfaces that task executors work with
public interface Future<V> {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}

public interface Callable<V> {
    V call() throws Exception;
}

// Spring's ListenableFuture (from spring-context) extends this foundation

Usage Examples

// Working with Future results
AsyncTaskExecutor executor = new SimpleAsyncTaskExecutor();

// Submit tasks and handle results
Future<Integer> calculation = executor.submit(() -> {
    // Expensive calculation
    Thread.sleep(2000);
    return 42;
});

Future<String> dataFetch = executor.submit(() -> {
    // Data fetching operation
    return fetchFromDatabase();
});

// Non-blocking check
if (calculation.isDone()) {
    try {
        Integer result = calculation.get();
        System.out.println("Calculation result: " + result);
    } catch (ExecutionException ex) {
        System.err.println("Calculation failed: " + ex.getCause());
    }
}

// Blocking wait with timeout
try {
    String data = dataFetch.get(5, TimeUnit.SECONDS);
    processData(data);
} catch (TimeoutException ex) {
    System.err.println("Data fetch timed out");
    dataFetch.cancel(true);
} catch (ExecutionException ex) {
    System.err.println("Data fetch failed: " + ex.getCause());
}

// Batch processing with CompletableFuture composition
List<Future<String>> futures = IntStream.range(0, 10)
    .mapToObj(i -> executor.submit(() -> processItem(i)))
    .collect(Collectors.toList());

// Wait for all to complete
List<String> results = futures.stream()
    .map(future -> {
        try {
            return future.get(30, TimeUnit.SECONDS);
        } catch (Exception ex) {
            return "Error: " + ex.getMessage();
        }
    })
    .collect(Collectors.toList());

Task Execution Patterns

Common Patterns and Best Practices

// Pattern 1: Fire-and-forget tasks
public class NotificationService {
    private final TaskExecutor taskExecutor;
    
    public NotificationService(TaskExecutor taskExecutor) {
        this.taskExecutor = taskExecutor;
    }
    
    public void sendNotification(String message, String recipient) {
        taskExecutor.execute(() -> {
            // Send email/SMS notification asynchronously
            emailService.send(recipient, message);
        });
    }
}

// Pattern 2: Producer-consumer with task decoration
public class AuditedTaskExecutor implements TaskExecutor {
    private final TaskExecutor delegate;
    private final AuditService auditService;
    
    public AuditedTaskExecutor(TaskExecutor delegate, AuditService auditService) {
        this.delegate = delegate;
        this.auditService = auditService;
    }
    
    @Override
    public void execute(Runnable task) {
        String taskId = UUID.randomUUID().toString();
        Runnable auditedTask = () -> {
            auditService.logTaskStart(taskId);
            long startTime = System.currentTimeMillis();
            try {
                task.run();
                auditService.logTaskSuccess(taskId, System.currentTimeMillis() - startTime);
            } catch (Exception ex) {
                auditService.logTaskFailure(taskId, ex);
                throw ex;
            }
        };
        delegate.execute(auditedTask);
    }
}

// Pattern 3: Graceful shutdown
public class GracefulTaskExecutor implements AsyncTaskExecutor, DisposableBean {
    private final AsyncTaskExecutor delegate;
    private final List<Future<?>> activeTasks = Collections.synchronizedList(new ArrayList<>());
    private volatile boolean shutdownRequested = false;
    
    public GracefulTaskExecutor(AsyncTaskExecutor delegate) {
        this.delegate = delegate;
    }
    
    @Override
    public Future<?> submit(Runnable task) {
        if (shutdownRequested) {
            throw new IllegalStateException("Executor is shutting down");
        }
        
        Future<?> future = delegate.submit(() -> {
            try {
                task.run();
            } finally {
                activeTasks.removeIf(f -> f.isDone() || f.isCancelled());
            }
        });
        
        activeTasks.add(future);
        return future;
    }
    
    @Override
    public void destroy() throws Exception {
        shutdownRequested = true;
        
        // Wait for active tasks to complete
        long deadline = System.currentTimeMillis() + 30000; // 30 second timeout
        while (!activeTasks.isEmpty() && System.currentTimeMillis() < deadline) {
            Thread.sleep(100);
            activeTasks.removeIf(f -> f.isDone() || f.isCancelled());
        }
        
        // Cancel remaining tasks
        activeTasks.forEach(future -> future.cancel(true));
    }
}

This task execution framework provides the foundation for Spring's asynchronous processing capabilities, enabling developers to build scalable, non-blocking applications with proper resource management and lifecycle control.

Install with Tessl CLI

npx tessl i tessl/maven-org-springframework--spring-core

docs

annotation-processing.md

aot-optimization.md

core-infrastructure.md

environment-config.md

index.md

resource-management.md

task-execution.md

type-conversion.md

utilities.md

tile.json