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

com.avaje.ebeaninternal.server.lib.thread.PooledThread Maven / Gradle / Ivy

/**
 *  Copyright (C) 2006  Robin Bygrave
 *  
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *  
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *  
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
package com.avaje.ebeaninternal.server.lib.thread;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * A thread that belongs to a ThreadPool. It will return to the Threadpool when
 * it has finished its assigned task.
 */
public class PooledThread implements Runnable {

	private static final Logger logger = Logger.getLogger(PooledThread.class.getName());
	
    /**
     * Create the PooledThread.
     */
    protected PooledThread(ThreadPool threadPool, String name, boolean isDaemon,
            Integer threadPriority) {

        this.name = name;
        this.threadPool = threadPool;
        this.lastUsedTime = System.currentTimeMillis();

        thread = new Thread(this, name);
        thread.setDaemon(isDaemon);

        if (threadPriority != null) {
            thread.setPriority(threadPriority.intValue());
        }
        //thread.start();
    }
    
    protected void start() {
    	thread.start();
    }
    
    /**
     * Assign work to this thread. The thread will notify the listener when it
     * has finished the work.
     */
    public boolean assignWork(Work work) {
        synchronized (workMonitor) {
            this.work = work;
            workMonitor.notifyAll();
        }
        return true;
    }

    /**
     * process any assigned work until stopped or interrupted.
     */
    public void run() {
        // process assigned work until we receive a shutdown signal
        synchronized (workMonitor) {
            while (!isStopping) {
                try {
                    if (work == null) {
                        workMonitor.wait();
                    }
                } catch (InterruptedException e) {
                }
                doTheWork();
            }
        }
        
        // Tell stop() we have shut ourselves down successfully
        synchronized (threadMonitor) {
            threadMonitor.notifyAll();
        }
        //Log.debug("PooledThread [" + getName() + "] finished ");
        isStopped = true;
    }

    /**
     * Actually do the work and gather the appropriate measures.
     */
    private void doTheWork() {
        if (isStopping){
            return;
        }

        long startTime = System.currentTimeMillis();
        if (work == null) {
            // probably shutting down the thread

        } else {
            try {
                work.setStartTime(startTime);
                work.getRunnable().run();

            } catch (Throwable ex) {
				logger.log(Level.SEVERE, null, ex);

                if (wasInterrupted) {
                    this.isStopping = true;
                    threadPool.removeThread(this);
                    logger.info("PooledThread [" + name + "] removed due to interrupt");
                    try {
                        thread.interrupt();
                    } catch (Exception e){
                    	String msg = "Error interrupting PooledThead["+name+"]";
        				logger.log(Level.SEVERE, msg, e);
                    }
                    return;
                }
            }
        }
        lastUsedTime = System.currentTimeMillis();
        totalWorkCount++;
        totalWorkExecutionTime = totalWorkExecutionTime + lastUsedTime - startTime;
        this.work = null;
        threadPool.returnThread(this);

    }

    /**
     * Try to interrupt the thread.
     * 

* If the Thread was interrupted then it will be removed from the pool. *

*/ public void interrupt() { // set a flag so doTheWork knows that it was interrupted // and removes rather than returns wasInterrupted = true; try { thread.interrupt(); } catch (SecurityException ex) { wasInterrupted = false; throw ex; } } /** * Returns true if the thread has finished. */ public boolean isStopped() { return isStopped; } /** * Stop the thread relatively nicely. It will wait a maximum of 10 seconds * for it to complete any existing work. */ protected void stop() { isStopping = true; synchronized (threadMonitor) { assignWork(null); //trace("stop assigned null work..."); try { threadMonitor.wait(10000); } catch (InterruptedException e) { ; } } thread = null; threadPool.removeThread(this); } /** * return the name of the thread. */ public String getName() { return name; } /** * Returns the currently executing work, otherwise null. */ public Work getWork() { return work; } /** * The total number of jobs this thread has run. */ public int getTotalWorkCount() { return totalWorkCount; } /** * The total time for performing all assigned work. */ public long getTotalWorkExecutionTime() { return totalWorkExecutionTime; } /** * Returns the time this thread was last used. */ public long getLastUsedTime() { return lastUsedTime; } /** * Flag to indicate that the thread was interrupted. */ private boolean wasInterrupted = false; /** * The time the thread was last used. */ private long lastUsedTime; /** * The work to run */ private Work work = null; /** * Set to indicate the thread is stopping. */ private boolean isStopping = false; /** * Set when the thread has stopped. */ private boolean isStopped = false; /** * The background thread. */ private Thread thread = null; /** * The pool this worker belongs to. */ private ThreadPool threadPool; /** * The name of the Thread */ private String name = null; /** * The thread synchronization object. */ private Object threadMonitor = new Object(); /** * The monitor for work notification. */ private Object workMonitor = new Object(); /** * Total number of work performed. */ private int totalWorkCount = 0; /** * Total work execution time. */ private long totalWorkExecutionTime = 0; }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy