01: /*
02: * Copyright 2006 The JA-SIG Collaborative. All rights reserved. See license
03: * distributed with this file and available online at
04: * http://www.uportal.org/license.html
05: */
06: package org.jasig.portal.events;
07:
08: import org.jasig.portal.PortalSessionManager;
09: import org.jasig.portal.utils.threading.PriorityThreadFactory;
10:
11: import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
12: import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue;
13: import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor;
14: import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
15:
16: /**
17: * Implementation of <code>EventListener</code> that assumes that
18: * EventHandlers will be doing something I/O Intensive that they may
19: * block users from seeing a "snappy" response, and thus call the <code>EventHandler</code>s in their own thread.
20: * <p>This uses The Backport Concurrent Library to provide threading and has the following defaults:
21: * <ul>
22: * <li>Initial Threads: 15</li>
23: * <li>Max Threads: 30</li>
24: * <li>Thread Priority: 5</li>
25: * </ul>
26: *
27: * @author Scott Battaglia
28: * @version $Revision: 36731 $ $Date: 2006-09-27 11:21:06 -0700 (Wed, 27 Sep 2006) $
29: * @since 2.6
30: *
31: */
32: public final class ThreadedEventListener extends AbstractEventListener {
33:
34: /** Default value for initial thread size. */
35: private static final int DEFAULT_INITIAL_THREADS = 15;
36:
37: /** Default value of the maximum number of threads. */
38: private static final int DEFAULT_MAX_THREADS = 30;
39:
40: /** Default thread priority. */
41: private static final int DEFAULT_THREAD_PRIORITY = 5;
42:
43: /** Instance of thread pool. */
44: private ExecutorService threadPool;
45:
46: /** Initial size of ThreadPool. */
47: private int initialThreads = DEFAULT_INITIAL_THREADS;
48:
49: /** Maximum size of ThreadPool. */
50: private int maxThreads = DEFAULT_MAX_THREADS;
51:
52: /** Priority of Threads. */
53: private int threadPriority = DEFAULT_THREAD_PRIORITY;
54:
55: protected void afterPropertiesSetInternal() throws Exception {
56: this .threadPool = new ThreadPoolExecutor(initialThreads,
57: maxThreads, 0L, TimeUnit.MILLISECONDS,
58: new LinkedBlockingQueue(), new PriorityThreadFactory(
59: threadPriority, "Priority",
60: PortalSessionManager.getThreadGroup()));
61: }
62:
63: protected void onApplicationEventInternal(final PortalEvent event,
64: final EventHandler handler) {
65: this .threadPool.execute(new Task(event, handler));
66: }
67:
68: public void setInitialThreads(final int initialThreads) {
69: this .initialThreads = initialThreads;
70: }
71:
72: public void setMaxThreads(final int maxThreads) {
73: this .maxThreads = maxThreads;
74: }
75:
76: public void setThreadPriority(final int threadPriority) {
77: this .threadPriority = threadPriority;
78: }
79:
80: private class Task implements Runnable {
81:
82: private final PortalEvent event;
83:
84: private final EventHandler handler;
85:
86: public Task(final PortalEvent event, final EventHandler handler) {
87: this .event = event;
88: this .handler = handler;
89: }
90:
91: public void run() {
92: this.handler.handleEvent(event);
93: }
94: }
95: }
|