All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nassimus.thread.BufferedBatchFlowControlExecutor Maven / Gradle / Ivy

There is a newer version: 1.0.9
Show newest version
package org.nassimus.thread;

import org.nassimus.thread.util.SimpleObjectPool;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

/*
* @author : Nassim MOUALEK
* [email protected]
* */
public abstract class BufferedBatchFlowControlExecutor extends FlowControlExecutor> {

    private BufferedBatchCallable callable;
    private List buffer;
    private SimpleObjectPool> buffersPool;
    private int bufferSize;

    public BufferedBatchFlowControlExecutor(BufferedBatchCallable callable, final int bufferSize, int nbThreads, int maxQueueSize, final String name) {
        super(nbThreads, maxQueueSize, name);
        this.bufferSize = bufferSize;
        this.callable = callable;
        this.buffer = new ArrayList<>();
        this.buffersPool = new SimpleObjectPool>(nbThreads){
            @Override
            public List createAnObject() {
                return new ArrayList(bufferSize);
            }
        };
    }

    public BufferedBatchFlowControlExecutor(int nbThreads, int maxQueueSize, final String name) {
        this(null,0, nbThreads, maxQueueSize, name );
    }
    public void submitWithException(T params) throws Throwable {
        submit(params);
        if (executionExceptions.size() > 0) {
            throw executionExceptions.poll();
        }
    }
    public void submit(T params) throws InterruptedException {
        if (isSubmitsEnds())
            throw new RuntimeException("No more task accepted");
        synchronized (buffer){
            buffer.add(params);
            if (buffer.size()==bufferSize){
                process();
            }
        }
    }
    public abstract boolean isSubmitsEnds();

    private void process() throws InterruptedException{
        if (!buffer.isEmpty())
        synchronized (this){
            if (buffer.isEmpty())
                return;
            final List newBuffer = buffersPool.checkOut();
            newBuffer.clear();
            newBuffer.addAll(buffer);
            buffer.clear();
            submit(new Callable() {
                @Override
                public void call() throws Exception {
                    callable.call(newBuffer);
                    buffersPool.release(newBuffer);
                }
            });
        }
    }

    private boolean shouldFlush(){
        return isSubmitsEnds() && !buffer.isEmpty();
    }

    public void waitAndFlushAndShutDown() throws InterruptedException {
        try {
            waitAndFlushAndShutDownWithException(false);
        } catch (Throwable e) {
            if (e instanceof InterruptedException)
                throw (InterruptedException)e;
        }
    }
    public void waitAndFlushAndShutDownWithException() throws Throwable {
        waitAndFlushAndShutDownWithException(true);
    }
    private void waitAndFlushAndShutDownWithException(boolean throwException) throws Exception {
        while(true){
            synchronized (emptyQueueLock) {
                try {
                    if (!isQueueEmpty())
                        emptyQueueLock.wait();
                    if (shouldFlush())
                        process();
                    if (throwException && executionExceptions.size() > 0) {
                        throw executionExceptions.poll();
                    }
                } finally {
                    if (shouldFlush()) {
                        process();
                    } else if ( isSubmitsEnds() && isQueueEmpty() ) {
                        break;
                    }
                }
            }
        }
        executor.shutdown();
        printLogStop();
    }

    @Override
    public String toString(long chunkSize) {
        return super.toString(chunkSize*bufferSize);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy