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

ch.randelshofer.quaqua.util.ConcurrentDispatcher Maven / Gradle / Ivy

Go to download

A Mavenisation of the Quaqua Mac OSX Swing Look and Feel (Java library) Quaqua Look and Feel (C) 2003-2010, Werner Randelshofer. Mavenisation by Matt Gumbley, DevZendo.org - for problems with Mavenisation, see Matt; for issues with Quaqua, see the Quaqua home page. For full license details, see http://randelshofer.ch/quaqua/license.html

The newest version!
/*
 * @(#)ConcurrentDispatcher.java  2.1  2009-06-01
 *
 * Copyright (c) 2002-2010 Werner Randelshofer
 * Hausmatt 10, Immensee, CH-6405, Switzerland
 * All rights reserved.
 *
 * You may not use, copy or modify this file, except in compliance with the
 * license agreement you entered into with Werner Randelshofer.
 * For details see accompanying license terms.
 */
package ch.randelshofer.quaqua.util;

import java.util.*;
import javax.swing.*;

/**
 * Processes Runnable objects concurrently on a pool of processor threads.
 * The order in which the runnable objects are processed is not
 * necesseraly the same in which they were added to the dispatcher.
 * There is one thread pool per instance.
 * 

* Design pattern used: Acceptor * Role in design pattern: EventCollector and EventProcessor *

* Example *
The following program prints "Hello World" on the * processor thread: *

 * // Create the Dispatcher.
 * ConcurrentDispatcher dispatcher = new ConcurrentDispatcher();
 *
 * // Create the Runnable object.
 * Runnable runner = new Runnable() {
 *     public void run()  {
 *         System.out.println("Hello World");
 *     }
 * };
 *
 * // Execute the Runnable objekt using the dispatcher.
 * dispatcher.dispatch(runner);
 * 
* * @author Werner Randelshofer, Hausmatt 10, Immensee, CH-6405, Switzerland * @version 2.1 2009-06-01 Added dispose method. *
2.0 2002-04-07 dispatchLIFO added. *
1.0 2002-05-18 Created. */ public class ConcurrentDispatcher { /** * The priority of the processor thread. */ private int priority; /** * The queue stores the events until they * can be processed by a processor thread. */ private final LinkedList queue = new LinkedList(); /** * Number of concurrent threads. */ private int threadCount; /** * Maximum number of concurrent threads. */ private int maxThreadCount; /** * Set the policy to enqueue the runnable * for later execution if there are no available * threads in the pool. */ public static final int ENQUEUE_WHEN_BLOCKED = 0; /** * Set the policy for blocked execution to be that * the current thread executes the command if there * are no available threads in the pool. */ public static final int RUN_WHEN_BLOCKED = 1; /** * The policy used when the maximal number of * threads is reached. */ private int blockingPolicy = ENQUEUE_WHEN_BLOCKED; /** * Creates a new ConcurrentDispatcher and * sets the priority of the processor thread to * java.lang.Thread.NORM_PRIORITY and with * up to five concurrent threads in the thread * pool. */ public ConcurrentDispatcher() { this(Thread.NORM_PRIORITY, 5); } /** * Creates a new ConcurrentDispatcher. * * @param priority The priority of the processor * thread. * @param maxThreadCount The maximal number of concurrent * threads in the thread pool. */ public ConcurrentDispatcher(int priority, int maxThreadCount) { this.priority = priority; this.maxThreadCount = maxThreadCount; } /** * Sets the maximum number of concurrent threads. * @param maxThreadCount Maximal number of concurrent threads. * A value of zero or below zero stops the dispatcher * when the queue is empty. */ public void setMaxThreadCount(int maxThreadCount) { this.maxThreadCount = maxThreadCount; } /** * Returns the maximal number of concurrent threads. */ public int getMaxThreadCount() { return maxThreadCount; } /** * Enqueues the Runnable object, and executes * it on a processor thread. */ public void dispatch(Runnable runner) { dispatch(runner, false); } /** * Enqueues the Runnable object, and executes * it on a processor thread. */ public void dispatch(Runnable runner, boolean isLIFO) { isLIFO = false; synchronized (queue) { if (threadCount < maxThreadCount) { if (isLIFO) { queue.addFirst(runner); } else { queue.addLast(runner); } Thread processor = new Thread(this + " Processor") { public void run() { processEvents(); } }; threadCount++; // The processor thread must not be a daemon, // or else the Java VM might stop before // all runnables have been processed. try { processor.setDaemon(false); } catch (SecurityException e) { e.printStackTrace(); } try { processor.setPriority(priority); } catch (SecurityException e) { e.printStackTrace(); } processor.start(); return; } else if (blockingPolicy == ENQUEUE_WHEN_BLOCKED) { if (isLIFO) { queue.addFirst(runner); } else { queue.addLast(runner); } return; } } //implicit: if (threadCount >= maxThreadCount && blockingPolicy == RUN_WHEN_BLOCKED) runner.run(); } public void stop() { } /** * This method dequeues all Runnable objects from the * queue and executes them. The method returns * when the queue is empty. */ protected void processEvents() { Object runner; loop: while (true) { synchronized (queue) { if (queue.isEmpty()) { threadCount--; break loop; } runner = queue.removeFirst(); } try { ((Runnable) runner).run(); } catch (Throwable e) { e.printStackTrace(); } } } /** * Disposes the dispatcher and all associated processes. */ public void dispose() { synchronized (queue) { queue.clear(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy