001: /*
002: * hgcommons 7
003: * Hammurapi Group Common Library
004: * Copyright (C) 2003 Hammurapi Group
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * URL: http://www.hammurapi.biz/hammurapi-biz/ef/xmenu/hammurapi-group/products/products/hgcommons/index.html
021: * e-Mail: support@hammurapi.biz
022: */
023: package biz.hammurapi.util;
024:
025: import java.util.LinkedList;
026:
027: /**
028: * Processes tasks from differen threads in a single thread.
029: * @author Pavel Vlasov
030: * @version $Revision: 1.6 $
031: */
032: public class SerialProcessor {
033:
034: private LinkedList tasks = new LinkedList();
035:
036: {
037: new Thread() {
038: {
039: setName("Task processing thread");
040: start();
041: }
042:
043: public void run() {
044: try {
045: while (true) {
046: Runnable task;
047: synchronized (tasks) {
048: while (tasks.isEmpty()) {
049: try {
050: tasks.wait();
051: } catch (InterruptedException e) {
052: return;
053: }
054: }
055:
056: task = (Runnable) tasks.removeFirst();
057: }
058:
059: if (task == null) {
060: return;
061: }
062:
063: try {
064: task.run();
065: } finally {
066: task.notifyAll();
067: }
068: }
069: } catch (Exception e) {
070: e.printStackTrace();
071: } finally {
072: synchronized (tasks) {
073: terminated = true;
074: tasks.notifyAll();
075: }
076: }
077: }
078: };
079:
080: Runtime.getRuntime().addShutdownHook(new Thread() {
081: public void run() {
082: synchronized (tasks) {
083: tasks.add(null);
084: tasks.notifyAll();
085: }
086: }
087: });
088: }
089:
090: private void checkTerminated() {
091: synchronized (tasks) {
092: if (terminated) {
093: throw new IllegalStateException(
094: "Task processing thread was terminated prematurely");
095: }
096: }
097: }
098:
099: private boolean terminated;
100:
101: /**
102: * Executes task in a separate thread
103: * @throws InterruptedException
104: */
105: public void execute(Runnable task) throws InterruptedException {
106: if (task != null) {
107: synchronized (tasks) {
108: checkTerminated();
109: tasks.add(task);
110: tasks.notifyAll();
111: }
112:
113: synchronized (task) {
114: task.wait();
115: }
116: }
117: }
118:
119: private static SerialProcessor defaultInstance;
120:
121: public static SerialProcessor getDefaultInstance() {
122: synchronized (SerialProcessor.class) {
123: if (defaultInstance == null) {
124: defaultInstance = new SerialProcessor();
125: }
126: }
127: return defaultInstance;
128: }
129: }
|