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

com.sun.jmx.remote.opt.util.JobExecutor Maven / Gradle / Ivy

/*
 * @(#)file      JobExecutor.java
 * @(#)author    Sun Microsystems, Inc.
 * @(#)version   1.6
 * @(#)lastedit  07/03/08
 * @(#)build     @BUILD_TAG_PLACEHOLDER@
 *
 * 
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU General
 * Public License Version 2 only ("GPL") or the Common Development and
 * Distribution License("CDDL")(collectively, the "License"). You may not use
 * this file except in compliance with the License. You can obtain a copy of the
 * License at http://opendmk.dev.java.net/legal_notices/licenses.txt or in the 
 * LEGAL_NOTICES folder that accompanied this code. See the License for the 
 * specific language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file found at
 *     http://opendmk.dev.java.net/legal_notices/licenses.txt
 * or in the LEGAL_NOTICES folder that accompanied this code.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.
 * 
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * 
 *       "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding
 * 
 *       "[Contributor] elects to include this software in this distribution
 *        under the [CDDL or GPL Version 2] license."
 * 
 * If you don't indicate a single choice of license, a recipient has the option
 * to distribute your version of this file under either the CDDL or the GPL
 * Version 2, or to extend the choice of license to its licensees as provided
 * above. However, if you add GPL Version 2 code and therefore, elected the
 * GPL Version 2 license, then the option applies only if the new code is made
 * subject to such option by the copyright holder.
 * 
 */ 

package com.sun.jmx.remote.opt.util;

import java.util.ArrayList;

class JobExecutor extends Thread {

    /**
     * Constructs a JobExecutor.
     *
     * @param job
     */
    private JobExecutor(Runnable job) {
	super(tgroup, tname + counter++);
	setDaemon(true);

	this.job = job;
    }

    public static void setPoolSize(int size) {
	if (size < 0) {
	    throw new IllegalArgumentException("Negative size.");
	}

	poolSize = size;
    }

    public static int getPoolSize() {
	return poolSize;
    }


    public static void setWaitingTime(long time) {
	if (time < 0) {
	    throw new IllegalArgumentException("Negative waiting time.");
	}

	waitingTime = time;
    }

    public static long getWaitingTime() {
	return waitingTime;
    }


    public void run() {
	while (true) {
	    if (job != null) {
		try {
		    job.run();
		} catch (Exception e) {
		    if (logger.warningOn()) {
			logger.warning("run", "Got an unexpected exception.", e);
		    }
		} finally {
		    job = null;
		}
	    }

	    synchronized(lock) {
		synchronized(waitingList) {
		    if (waitingList.size() >= poolSize) {
			// too many waiting threads, dying
			terminated = true;

			break;
		    } else { // waiting a job
			waitingList.add(this);
		    }
		}

		// waiting	    
		long remainingTime = waitingTime;
		final long startTime = System.currentTimeMillis();

		while (job == null && remainingTime > 0) {
		    try {
			lock.wait(remainingTime);
		    } catch (InterruptedException ie) {
			// in this step, should not happen
			// clean
			this.interrupted();
		    }

		    remainingTime = waitingTime - (System.currentTimeMillis() - startTime);
		}

		// end waiting
		boolean removed;
		synchronized(waitingList) {
		    removed = waitingList.remove(this);
		}
		
		if (!removed) { // let's wait new job
		    while (job == null) {
			try {
			    lock.wait();
			} catch (InterruptedException ire) {
			    // in this step, should not happen
			    // clean
			    this.interrupted();
			}
		    }

		    // go back to execute the job.
		    continue;
		} else { // bye
		    terminated = true;
		    break;		
		}
	    }
	}
    }

    /**
     * Executes a job.
     */
    public static void handoff(Runnable job) {
	JobExecutor je = null;

	synchronized(waitingList) {
	    if (waitingList.size() > 0) {
		je = (JobExecutor)waitingList.remove(0);
	    }
	}

	if (je != null) {
	    synchronized(je.lock) {
		if (!je.terminated) {
		    je.job = job;
		    je.lock.notify(); // wakeup the thread
		} else {
		    je = null;
		}
	    }
	}

	if (je == null) { // no more free thread, create a new one
	    je = new JobExecutor(job);
	    je.start();
	}    }

// instance variables
    private Runnable job = null;
    private int[] lock = new int[0];
    private boolean terminated = false;

// private variables
    private static int poolSize = 20;
    private static ArrayList waitingList = new ArrayList(poolSize);

    private static long counter = 0;
    private static long waitingTime = 300000; // 5 minutes

    private static final ThreadGroup tgroup = new ThreadGroup("Job_Executor");
    private static final String tname = "Job_Executor";

    private static final ClassLogger logger = 
	new ClassLogger("com.sun.jmx.remote.opt.util", 
			"JobExecutor");
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy