Skip to content

Performing tasks in parallel with different priorities

Roberto Gentili edited this page Dec 5, 2021 · 18 revisions

The BackgroundExecutor component you is able to run different functional interfaces in parallel by setting the priority of the thread they will be assigned to. There is also the option to wait for them start or finish.

For obtaining threads this component uses the ThreadSupplier that is also used by the IterableObjectHelper to iterate collections or arrays in parallel The ThreadSupplier can be customized in the burningwave.static.properties file and it provides a fixed number of reusable threads indicated by the 'thread-supplier.max-poolable-thread-count' property and, if these threads have already been assigned, new non-reusable threads will be created whose quantity maximum is indicated by the 'thread-supplier.max-detached-thread-count' property. Once this limit is reached if the request for a new thread exceeds the waiting time indicated by the 'thread-supplier.poolable-thread-request-timeout' property, the ThreadSupplier will proceed to increase the limit indicated by the 'thread-supplier.max-detached-thread-count' property for the quantity indicated by the 'thread-supplier.max-detached-thread-count.increasing-step' property. Resetting the 'thread-supplier.max-detached-thread-count' property to its initial value, will occur gradually only when there have been no more waits on thread requests for an amount of time indicated by the 'thread-supplier.max-detached-thread-count.elapsed-time-threshold-from-last-increase-for-gradual-decreasing-to-initial-value' property.

import static org.burningwave.core.assembler.StaticComponentContainer.BackgroundExecutor;

import org.burningwave.core.ManagedLogger;
import org.burningwave.core.concurrent.QueuedTasksExecutor.ProducerTask;
import org.burningwave.core.concurrent.QueuedTasksExecutor.Task;


public class TaskLauncher implements ManagedLogger {
    
    public void launch() {
        ProducerTask<Long> taskOne = BackgroundExecutor.createProducerTask(task -> {
            Long startTime = System.currentTimeMillis();
            logInfo("task one started");
            synchronized (this) {                
                wait(5000);
            }
            Task internalTask = BackgroundExecutor.createTask(tsk -> {
                logInfo("internal task started");    
                synchronized (this) {                
                    wait(5000);
                }
                logInfo("internal task finished");    
            }, Thread.MAX_PRIORITY).submit();
            internalTask.waitForFinish();
            logInfo("task one finished");
            return startTime;
        }, Thread.MAX_PRIORITY);
        taskOne.submit();
        Task taskTwo = BackgroundExecutor.createTask(task -> {
            logInfo("task two started and wait for task one finishing");
            taskOne.waitForFinish();
            logInfo("task two finished");    
        }, Thread.NORM_PRIORITY);
        taskTwo.submit();
        ProducerTask<Long> taskThree = BackgroundExecutor.createProducerTask(task -> {
            logInfo("task three started and wait for task two finishing");
            taskTwo.waitForFinish();
            logInfo("task two finished");
            return System.currentTimeMillis();
        }, Thread.MIN_PRIORITY);
        taskThree.submit();
        taskThree.waitForFinish();
        logInfo("Elapsed time: {}ms", taskThree.join() - taskOne.join());
    }
    
    public static void main(String[] args) {
        new TaskLauncher().launch();
    }
    
}

Examples of use of some components:

BackgroundExecutor
ClassFactory
ClassHunter
ClassPathHunter
CodeExecutor
Constructors
Fields
FileSystemItem
FunctionalInterfaceFactory
IterableObjectHelper
JavaMemoryCompiler
Methods
PathHelper
PropertyAccessor
UnitSourceGenerator

HitCount

Clone this wiki locally