/******************************************************************************* * Copyright (c) 2009 MATERNA Information & Communications. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html. For further * project-related information visit http://www.ws4d.org. The most recent * version of the JMEDS framework can be obtained from * http://sourceforge.net/projects/ws4d-javame. ******************************************************************************/ package org.ws4d.java.structures; /** * Synchronized Queue. The enqueueing thread must wait, until someone takes the * object out of the queue. */ public class WaitingQueue extends Queue { /* * (non-Javadoc) * @see org.ws4d.java.structures.Queue#get() */ protected Object getFirstElement() { return notifyObjectRemoved((SyncContainer)super.getFirstElement()); } /* (non-Javadoc) * @see org.ws4d.java.structures.Queue#addElement(java.lang.Object, int) */ protected void addElement(Object o, int index) { SyncContainer syncContainer = new SyncContainer(o); super.addElement(syncContainer, index); synchronized (syncContainer) { while (syncContainer.inQueue) { try { //Stops thread which enqueues the object, until someone takes it out of the queue. syncContainer.wait(); } catch (InterruptedException e) { } } } } /** * Returns an iterator for this queue. * <p> * This iterator allows to access every item inside this queue. * If an element is removed using this iterator the waiting thread will be notified. * </p> * * @return the iterator for this queue. */ public synchronized Iterator iterator() { final Iterator superIter = super.iterator(); return new Iterator() { private SyncContainer lastReturnedEntry = null; public void remove() { superIter.remove(); notifyObjectRemoved(lastReturnedEntry); } public Object next() { lastReturnedEntry = (SyncContainer)superIter.next(); return lastReturnedEntry.theObject; } public boolean hasNext() { return superIter.hasNext(); } }; } /** * Removes all entries from this queue and notifies all waiting thread. */ public synchronized void clear() { Iterator iter = iterator(); while (iter.hasNext()) { iter.next(); iter.remove(); } this.notifyAll(); } private Object notifyObjectRemoved(SyncContainer syncContainer) { synchronized (syncContainer) { syncContainer.inQueue = false; syncContainer.notifyAll(); } return syncContainer.theObject; } private class SyncContainer { Object theObject; volatile boolean inQueue = true; SyncContainer(Object o) { theObject = o; } } }