Package org.objectweb.celtix.bus.workqueue

Source Code of org.objectweb.celtix.bus.workqueue.AutomaticWorkQueueImpl

package org.objectweb.celtix.bus.workqueue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.objectweb.celtix.common.logging.LogUtils;
import org.objectweb.celtix.workqueue.AutomaticWorkQueue;

public class AutomaticWorkQueueImpl extends ThreadPoolExecutor implements AutomaticWorkQueue {

    static final int DEFAULT_MAX_QUEUE_SIZE = 128;
    private static final Logger LOG =
        LogUtils.getL7dLogger(AutomaticWorkQueueImpl.class);
   
    int maxQueueSize;

    AutomaticWorkQueueImpl(int mqs, int initialThreads, int highWaterMark, int lowWaterMark,
                           long dequeueTimeout) {
       
        super(-1 == lowWaterMark ? Integer.MAX_VALUE : lowWaterMark,
            -1 == highWaterMark ? Integer.MAX_VALUE : highWaterMark,
                TimeUnit.MILLISECONDS.toMillis(dequeueTimeout), TimeUnit.MILLISECONDS,
                mqs == -1 ? new ArrayBlockingQueue<Runnable>(DEFAULT_MAX_QUEUE_SIZE)
                    : new ArrayBlockingQueue<Runnable>(mqs));
       
        maxQueueSize = mqs == -1 ? DEFAULT_MAX_QUEUE_SIZE : mqs;
        lowWaterMark = -1 == lowWaterMark ? Integer.MAX_VALUE : lowWaterMark;
        highWaterMark = -1 == highWaterMark ? Integer.MAX_VALUE : highWaterMark;
               
        StringBuffer buf = new StringBuffer();
        buf.append("Constructing automatic work queue with:\n");
        buf.append("max queue size: " + maxQueueSize + "\n");
        buf.append("initialThreads: " + initialThreads + "\n");
        buf.append("lowWaterMark: " + lowWaterMark + "\n");
        buf.append("highWaterMark: " + highWaterMark + "\n");
        LOG.fine(buf.toString());

        if (initialThreads > highWaterMark) {
            initialThreads = highWaterMark;
        }

        // as we cannot prestart more core than corePoolSize initial threads, we temporarily
        // change the corePoolSize to the number of initial threads
        // this is important as otherwise these threads will be created only when the queue has filled up,
        // potentially causing problems with starting up under heavy load
        if (initialThreads < Integer.MAX_VALUE && initialThreads > 0) {
            setCorePoolSize(initialThreads);
            int started = prestartAllCoreThreads();
            if (started < initialThreads) {
                LOG.log(Level.WARNING, "THREAD_START_FAILURE_MSG", new Object[] {started, initialThreads});
            }
            setCorePoolSize(lowWaterMark);
        }
    }

    public String toString() {
        StringBuffer buf = new StringBuffer();
        buf.append(super.toString());
        buf.append(" [queue size: ");
        buf.append(getSize());
        buf.append(", max size: ");
        buf.append(maxQueueSize);
        buf.append(", threads: ");
        buf.append(getPoolSize());
        buf.append(", active threads: ");
        buf.append(getActiveCount());
        buf.append(", low water mark: ");
        buf.append(getLowWaterMark());
        buf.append(", high water mark: ");
        buf.append(getHighWaterMark());
        buf.append("]");
        return buf.toString();
    }
   
    // WorkQueue interface
    
    /* (non-Javadoc)
     * @see org.objectweb.celtix.workqueue.WorkQueue#execute(java.lang.Runnable, long)
     */
    public void execute(Runnable work, long timeout) {
        try {
            execute(work);
        } catch (RejectedExecutionException ree) {
            try {
                getQueue().offer(work, timeout, TimeUnit.MILLISECONDS);
            } catch (InterruptedException ie) {
                throw new RejectedExecutionException(ie);
            }
        }   
    }

    /* (non-Javadoc)
     * @see org.objectweb.celtix.workqueue.WorkQueue#schedule(java.lang.Runnable, long)
     */
    public void schedule(final Runnable work, final long delay) {
        // temporary implementation, replace with shared long-lived scheduler
        // task
        execute(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(delay);
                } catch (InterruptedException ie) {
                    // ignore
                }
                work.run();
            }
        });
    }
   
    // AutomaticWorkQueue interface
   
    public void shutdown(boolean processRemainingWorkItems) {
        if (!processRemainingWorkItems) {
            getQueue().clear();
        }
        shutdown();   
    }

    /**
     * Gets the maximum size (capacity) of the backing queue.
     * @return the maximum size (capacity) of the backing queue.
     */
    long getMaxSize() {
        return maxQueueSize;
    }

    /**
     * Gets the current size of the backing queue.
     * @return the current size of the backing queue.
     */
    public long getSize() {
        return getQueue().size();
    }


    public boolean isEmpty() {
        return getQueue().size() == 0;
    }

    boolean isFull() {
        return getQueue().remainingCapacity() == 0;
    }

    int getHighWaterMark() {
        int hwm = getMaximumPoolSize();
        return hwm == Integer.MAX_VALUE ? -1 : hwm;
    }

    int getLowWaterMark() {
        int lwm = getCorePoolSize();
        return lwm == Integer.MAX_VALUE ? -1 : lwm;
    }

    void setHighWaterMark(int hwm) {
        setMaximumPoolSize(hwm < 0 ? Integer.MAX_VALUE : hwm);
    }

    void setLowWaterMark(int lwm) {
        setCorePoolSize(lwm < 0 ? 0 : lwm);
    }
}
TOP

Related Classes of org.objectweb.celtix.bus.workqueue.AutomaticWorkQueueImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.