4

Essentially what I want is a BlockingQueue of size=1. I have a "listener" thread that simply waits, blocking until an object is put into the queue, and then retrieves it--and a "producer" thread that actually puts the object into the queue.

I can implement this with some synchronized blocks and a BlockingQueue implementation, but that seems like overkill. Is there a better, simpler way to do what I want?

Example interface:

public interface Wait<T> {
  /**
   * If "put" has never been called on this object, then this method will
   * block and wait until it has. Once "put" has been called with some T, this
   * method will return that T immediately.
   */
  public T get() throws InterruptedException;

  /**
   * @param object The object to return to callers of get(). If called more
   * than once, will throw an {@link IllegalStateException}.
   */
  public void put(T object);
}
1
  • 2
    Well, that's exactly what the bounded new ArrayBlockingQueue(1) is for (use the 'add' method, not 'put'). The object is pretty lightweight in terms of synchronization and the memory overhead shouldn't hurt unless you have tens of thousands of them. Do you have any special concerns? Commented Oct 20, 2008 at 23:47

2 Answers 2

4

You mean something like SynchronousQueue? Another useful class is Exchanger

Sign up to request clarification or add additional context in comments.

2 Comments

No, not quite. I've added a more specific example of exactly what I'm looking for.
SynchronousQueue has a size of 0.
4

I found code for a class called "ObjectLatch" here: http://forums.sun.com/thread.jspa?threadID=5321141

package jfco.progs;

import java.util.concurrent.CountDownLatch;

/**
 * <H1>A Blocking Object Latch</H1> This class implements a blocking object
 * latch, that acts as a synchronizer between a producer of an object and it's
 * consumer(s).
 * <p>
 * An object is set with <code>set()</code>only ONCE. Further attempts to set
 * the object are just ignored.<br>
 * <p>
 * Consumers request the object with <code>get()</code>. If the object is not
 * already set, consumers are blocked waiting until the object is available or <br>
 * until an interrupt (InteruptedException) terminates the wait.
 * <p>
 * The latch can be tested for object availability with isAvailable(), which
 * answers true if the object has already been set. <br>
 */
public class ObjectLatch<R> {

    /** The object. */
    private R object = null;

    /** The latch counter created and set to 1. */
    private final CountDownLatch latch = new CountDownLatch(1);

    /**
     * Checks if the object is already available (has been already set).
     * 
     * @return true, if the object is already available (has been already set)
     */
    public boolean isAvailable() {
        return latch.getCount() == 0;
    }

    /**
     * Sets the object if it is not already set. Otherwise ignore this request.
     * 
     * @param object
     *            the object
     */
    public synchronized void set(R object) {
        if (!isAvailable()) {
            this.object = object;
            latch.countDown();
        }
    }

    /**
     * Get the object if it is already available (has already been set).
     * <p>
     * If it is not available, wait until it is or until an interrupt
     * (InterruptedException) terminates the wait.
     * 
     * @return the object if it is already available (has already been set)
     * 
     * @throws InterruptedException
     */
    public R get() throws InterruptedException {
        latch.await();
        synchronized (this) {
            return object;
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.