Waiting for object value to be available.

classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|

Waiting for object value to be available.

Peter Veentjer - Anchor Men
 
 
I have the following problem.
 
I want some kind of container that can store an object. Multiple threads can read a value from that container, and if there is no object available (the value is null) they are going to sleep (or sleep untill a timeout occurs). If there is a value available, all threads that where sleeping wake up.. and read the value (but don`t remove it like a in blockingqueue)
 
The problem:
-A good name for such a structure. At the moment I have NotNullWaiter, but well.. that sucks.
-I want to know if there exist something like it.
 
And I would like it if you would have a look at my code.
 
public class NotNullWaiter<E> {
 
 private final ReadWriteLock _lock;
 private final Condition _itemAvailable;
 private volatile E _item;
 
 public NotNullWaiter(){
  this(false);
 }
 
 public NotNullWaiter(boolean fair){
  _lock = new ReentrantReadWriteLock(fair);
  _itemAvailable = _lock.writeLock().newCondition();
 }
 
 public E read()throws InterruptedException{
  _lock.readLock().lockInterruptibly();
 
  try{
   while(_item==null)
    _itemAvailable.wait();
 
   return _item;
  }finally{
   _lock.readLock().unlock();
  }
 }
 
 public E read(long timeout, TimeUnit timeUnit)throws InterruptedException{
  if(timeUnit == null)throw new NullPointerException();
 
  _lock.readLock().lockInterruptibly();
 
  try{
   long nanos = timeUnit.toNanos(timeout);
   for (;;) {
    //if there is an item available, return it.
    if (_item !=null)
     return _item;
 
    //if the time has passed, return null to indicate no item is available.
    if (nanos <= 0)
     return null;
 
    try {
     nanos = _itemAvailable.awaitNanos(nanos);
    } catch (InterruptedException ie) {
     _itemAvailable.signal(); // propagate to non-interrupted thread (todo: why???)
     throw ie;
    }
   }
  }finally{
   _lock.readLock().unlock();
  }
 }
 
 public void write(E item)throws InterruptedException{
     _lock.writeLock().lockInterruptibly();
 
  try{
   _item = item;
   if(item != null)
    _itemAvailable.signalAll();
  }finally{
   _lock.writeLock().unlock();
  }
 }
 
 /*
 private void write(E e, long timeout, TimeUnit timeUnit)throws InterruptedException{
    if(timeUnit == null)throw new NullPointerException();
 
  _lock.writeLock().lockInterruptibly();
  try{
      long nanos = timeUnit.toNanos(timeout);
            for (;;) {
 
   }
  }finally{
   _lock.writeLock().unlock();
  }
 } */
}

Met vriendelijke groet,

Peter
Veentjer
Anchor Men Interactive Solutions – duidelijk in zakelijke internetoplossingen

Praediniussingel 41
9711 AE Groningen

T: 050-3115222
F: 050-5891696
E: <A title="mailto:p.veentjer@anchormen.nl&#10;mailto:f.b.smit@anchormen.nl" href="BLOCKED::mailto:p.veentjer@anchormen.nl">p.veentjer@...
I : <A title="blocked::http://www.anchormen.nl/&#10;http://www.anchormen.nl/" href="BLOCKED::blocked::http://www.anchormen.nl/">www.anchormen.nl

 

Met vriendelijke groet,

Peter
Veentjer
Anchor Men Interactive Solutions – duidelijk in zakelijke internetoplossingen

Praediniussingel 41
9711 AE Groningen

T: 050-3115222
F: 050-5891696
E: [hidden email]
I : <A title=http://www.anchormen.nl/ href="blocked::http://www.anchormen.nl/">www.anchormen.nl

 

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Waiting for object value to be available.

Peter Veentjer - Anchor Men
A Future is meant to be used a single time. My structure needs to be updated null/value/value/null/value etc many many times and threads waiting for a value need to sleep if there is no value.

You can`t unset a Future.. My structure needs to be set/unset many times.  

-----Oorspronkelijk bericht-----
Van: Michael Hicks [mailto:[hidden email]]
Verzonden: dinsdag 23 augustus 2005 14:08
Aan: Peter Veentjer - Anchor Men
Onderwerp: Re: [concurrency-interest] Waiting for object value to be available.

Looks similar to a Future, and you might be able to use a FutureTask instead of your code below, depending on how you want to implement creation of the stored value; see http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/
Future.html.

Mike

On Aug 23, 2005, at 8:00 AM, Peter Veentjer - Anchor Men wrote:

>  
>  
> I have the following problem.
>  
> I want some kind of container that can store an object. Multiple
> threads can read a value from that container, and if there is no
> object available (the value is null) they are going to sleep (or sleep
> untill a timeout occurs). If there is a value available, all threads
> that where sleeping wake up.. and read the value (but don`t remove it
> like a in blockingqueue)
>  
> The problem:
> -A good name for such a structure. At the moment I have NotNullWaiter,
> but well.. that sucks.
> -I want to know if there exist something like it.
>  
> And I would like it if you would have a look at my code.
>  
> public class NotNullWaiter<E> {
>  
>  private final ReadWriteLock _lock;
>  private final Condition _itemAvailable;
>  private volatile E _item;
>  
>  public NotNullWaiter(){
>   this(false);
>  }
>  
>  public NotNullWaiter(boolean fair){
>   _lock = new ReentrantReadWriteLock(fair);
>   _itemAvailable = _lock.writeLock().newCondition();
>  }
>  
>  public E read()throws InterruptedException{
>   _lock.readLock().lockInterruptibly();
>  
>   try{
>    while(_item==null)
>     _itemAvailable.wait();
>  
>    return _item;
>   }finally{
>    _lock.readLock().unlock();
>   }
>  }
>  
>  public E read(long timeout, TimeUnit timeUnit)throws
> InterruptedException{
>   if(timeUnit == null)throw new NullPointerException();
>  
>   _lock.readLock().lockInterruptibly();
>  
>   try{
>    long nanos = timeUnit.toNanos(timeout);
>    for (;;) {
>     //if there is an item available, return it.
>     if (_item !=null)
>      return _item;
>  
>     //if the time has passed, return null to indicate no item is
> available.
>     if (nanos <= 0)
>      return null;
>  
>     try {
>      nanos = _itemAvailable.awaitNanos(nanos);
>     } catch (InterruptedException ie) {
>      _itemAvailable.signal(); // propagate to non-interrupted thread
> (todo: why???)
>      throw ie;
>     }
>    }
>   }finally{
>    _lock.readLock().unlock();
>   }
>  }
>  
>  public void write(E item)throws InterruptedException{
>      _lock.writeLock().lockInterruptibly();
>  
>   try{
>    _item = item;
>    if(item != null)
>     _itemAvailable.signalAll();
>   }finally{
>    _lock.writeLock().unlock();
>   }
>  }
>  
>  /*
>  private void write(E e, long timeout, TimeUnit timeUnit)throws
> InterruptedException{
>     if(timeUnit == null)throw new NullPointerException();
>  
>   _lock.writeLock().lockInterruptibly();
>   try{
>       long nanos = timeUnit.toNanos(timeout);
>             for (;;) {
>  
>    }
>   }finally{
>    _lock.writeLock().unlock();
>   }
>  } */
> }
>
> Met vriendelijke groet,
>
> Peter Veentjer
> Anchor Men Interactive Solutions - duidelijk in zakelijke
> internetoplossingen
>
> Praediniussingel 41
> 9711 AE Groningen
>
> T: 050-3115222
> F: 050-5891696
> E: [hidden email]
> I : www.anchormen.nl
>  
>
> Met vriendelijke groet,
>
> Peter Veentjer
> Anchor Men Interactive Solutions - duidelijk in zakelijke
> internetoplossingen
>
> Praediniussingel 41
> 9711 AE Groningen
>
> T: 050-3115222
> F: 050-5891696
> E: [hidden email]
> I : www.anchormen.nl
>  _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Waiting for object value to be available.

Gregg Wonderly-2
In reply to this post by Peter Veentjer - Anchor Men


Peter Veentjer - Anchor Men wrote:
> I want some kind of container that can store an object. Multiple threads
> can read a value from that container, and if there is no object
> available (the value is null) they are going to sleep (or sleep untill a
> timeout occurs). If there is a value available, all threads that where
> sleeping wake up.. and read the value (but don`t remove it like a in
> blockingqueue)

This is what the whole j.u.c.Future interface is for.  Have a look there
and the pointers from that Javadoc to FutureTask etc.

Gregg Wondely
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Waiting for object value to be available.

Peter Veentjer - Anchor Men
In reply to this post by Peter Veentjer - Anchor Men
I have used Futures but if understand them correct they are meant for
the completion of tasks. And my implementation is not based on the
completion of tasks.

Maybe you could elaborate on your suggestion. And please keep in mind
that the value wrapper will be updated many many times.. A Future only
completes once..


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Waiting for object value to be available.

Aleksey Gureiev
Peter,

Maybe I will sound a bit stupid, but why not using a bounded queue for
tasks. It looks like a classical multiple providers vs. multiple
consumers problem. The consumers are sleeping while there's no object in
the queue. When provider puts an object, first consumer gets awaken and
takes the object into processing.

If you think that it matches your scenario I can give you a short sample
on demand.

Thanks,

Aleksey Gureev
Noizeramp Creative Group
Home: http://www.noizeramp.com/
Blog: http://blog.noizeramp.com/

On Tue, 2005-08-23 at 16:00 +0200, Peter Veentjer - Anchor Men wrote:

> I have used Futures but if understand them correct they are meant for
> the completion of tasks. And my implementation is not based on the
> completion of tasks.
>
> Maybe you could elaborate on your suggestion. And please keep in mind
> that the value wrapper will be updated many many times.. A Future only
> completes once..
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Waiting for object value to be available.

Peter Veentjer - Anchor Men
In reply to this post by Peter Veentjer - Anchor Men

The difference with a bounded queue is that the item from the bounded queue will be removed and that isn`t what I want. A lot of readers may use the item that is in the container, but they don`t remove it. Only when I set the item to null, the item will be removed and all request for an item value will result in a block (untill a new item is available again).

So a BlockingQueue looks a lot like it.. But there is a difference.

 

Met vriendelijke groet,

Peter
Veentjer
Anchor Men Interactive Solutions – duidelijk in zakelijke internetoplossingen

Praediniussingel 41
9711 AE Groningen

T: 050-3115222
F: 050-5891696
E: [hidden email]
I : <A title=http://www.anchormen.nl/ href="blocked::http://www.anchormen.nl/">www.anchormen.nl

 

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Waiting for object value to be available.

Doug Lea
In reply to this post by Peter Veentjer - Anchor Men
Peter Veentjer - Anchor Men wrote:

>  
>  
> I have the following problem.
>  
> I want some kind of container that can store an object. Multiple threads
> can read a value from that container, and if there is no object
> available (the value is null) they are going to sleep (or sleep untill a
> timeout occurs). If there is a value available, all threads that where
> sleeping wake up.. and read the value (but don`t remove it like a in
> blockingqueue)

I think the most common approach to this sort of problem is to use
an Observer or Listener design. (My CPJ book includes a description
in section 3.5.2). This might be overkill here if you don't want or
need to otherwise maintain observers in lists and multicast to them
change notifications. If so, you might be able to make a simple
custom synchronization scheme. One possibility is to associate a version
number with your data objects, and have the observer threads wait
for versions to change from their last known version, and signalling
all waiters when they do change. Note that in these kinds of schemes
though, observers might miss seeing one of the versions. If that's not
OK, you probably need a full listener/multicast design to allow
tighter coordination.

-Doug

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Waiting for object value to be available.

Peter Veentjer - Anchor Men
In reply to this post by Peter Veentjer - Anchor Men
I think the most common approach to this sort of problem is to use
an Observer or Listener design. (My CPJ book includes a description
in section 3.5.2). This might be overkill here if you don't want or
need to otherwise maintain observers in lists and multicast to them
change notifications.
------------------------
It is very important that the threads that want to read the value, are
going to sleep untill a value is available. I think it is more complex
to create this behaviour by using a observer/observable than a
small concurrency stone.
 
And you could see the wait/notify functionality of java as a
observer/observable. The observers (threads) are waiting in a list (every java object
can have a collection of threads waiting to be notified) and the event
would be the signal. So I don`t see the need to create java objects for
something that already is in the core of Java.
 
Let me explain where this NullWaiter is going to be part of. I need
something that can be compared to a ThreadPoolExecutor. But I don`t
want to execute a single job, but I want to execute a job by all
threads in that structure repeatedly (untill the task is set to null). I have
called this structure the Repeater. The NullWaiter is going to be
part of the Repeater and contains the task all threads are waiting for.
If no task is available, all threads wait. But if a task is available,
they will keep repeating it..over.. and over.. and over.
 
Why do I need such a strange beast? It is going to be part
of a channels project I`m writing. One of the usages is that a
Repeater is going to 'suck' messages out of a channel.
 
example:
 
 public static void main(String[] args){
  Channel<FetchRequest> requestChannel = new StdBufferedChannel<FetchRequest>(500);
  Channel<FetchResult> resultChannel = new StdBufferedChannel<FetchResult>(50);
 
  RepeaterService fetchRepeater = new StdRepeaterService(5);//5 threads
  fetchRepeater.start();
  Fetcher fetcher = new Fetcher(requestChannel,resultChannel,fetchRepeater);
 
  RepeaterService analyzeRepeater = new StdRepeaterService(1);//1 thread
  analyzeRepeater.start();
  Analyzer analyzer = new Analyzer(resultChannel,requestChannel,analyzerExecutor);
 
  try {
       requestChannel.put(new FetchRequest(new URL("http://dmoz.org/")));
  } catch (InterruptedException e) {
   e.printStackTrace();
  } catch (MalformedURLException e) {
   e.printStackTrace();
  }
 }
 
 
 
 



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Waiting for object value to be available.

tpeierls
Peter Veentjer - Anchor Men wrote:
> Let me explain where this NullWaiter is going to be part of. I need
> something that can be compared to a ThreadPoolExecutor. But I don`t
> want to execute a single job, but I want to execute a job by all
> threads in that structure repeatedly (untill the task is set to null). I have
> called this structure the Repeater. The NullWaiter is going to be
> part of the Repeater and contains the task all threads are waiting for.
> If no task is available, all threads wait. But if a task is available,
> they will keep repeating it..over.. and over.. and over.

I still don't really understand the use case, but does this interface describe
what you want?

   interface AwaitableValue<V> {
       V get() throws InterruptedException;
       void set(V value);
   }

And if so, does this simpler implementation (doesn't use RWL) meet your needs?

   class SimpleAwaitableValue<V> implements AwaitableValue<V> {
       private volatile V value;
       public V get() throws InterruptedException {
           V v = value;
           if (v != null) return v;
           synchronized (this) {
               while (value == null) wait();
               return value;
           }
       }
       public synchronized void set(V v) {
           value = v;
           if (value != null) notifyAll();
       }
   }

--tim

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Waiting for object value to be available.

Peter Veentjer - Anchor Men
In reply to this post by Peter Veentjer - Anchor Men

I still don't really understand the use case, but does this interface describe
what you want?
 
--------------------------------------
 
Yes it does.. I allready had removed the read write lock but your name is a lot better than mine :)
 
public class Bar<E> {
 private final ReentrantLock _lock;
 private volatile E _item;
 private final Condition _availableCond;
 public Bar(boolean fair){
  _lock = new ReentrantLock(fair);
  _availableCond = _lock.newCondition();
 }
 public E get() throws InterruptedException {
  _lock.lockInterruptibly();
  try{
   while(_item == null)
    _availableCond.wait();
   return _item;
  }finally{
   _lock.unlock();
  }
 }
 public void set(E item) throws InterruptedException {
  _lock.lockInterruptibly();
  try{
   _item = item;
   if(_item!=null)
    _availableCond.signalAll();
  }finally{
   _lock.unlock();
  }
 }
}

 
But I`m going to need the read write lock. I don`t want multiple values of the WaitableValue out there.. only one is allowed (I only want one task-instance running, not two).. So I`m going to use the read write lock to garantuee that all old values are returned before a new value is available.


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Waiting for object value to be available.

Shaffer, Darron
In reply to this post by Peter Veentjer - Anchor Men
The old WaitableReference class would do this nicely.  Unfortunately, it
didn't make it into Java 5.

By the way, why didn't this group of classes end up in Java 5?


-----Original Message-----
From: [hidden email]
[mailto:[hidden email]] On Behalf Of Peter
Veentjer - Anchor Men
Sent: Tuesday, August 23, 2005 12:00 PM
To: Doug Lea; [hidden email]
Subject: RE: [concurrency-interest] Waiting for object value to be
available.

I think the most common approach to this sort of problem is to use
an Observer or Listener design. (My CPJ book includes a description
in section 3.5.2). This might be overkill here if you don't want or
need to otherwise maintain observers in lists and multicast to them
change notifications.
------------------------
It is very important that the threads that want to read the value, are
going to sleep untill a value is available. I think it is more complex
to create this behaviour by using a observer/observable than a
small concurrency stone.
 
And you could see the wait/notify functionality of java as a
observer/observable. The observers (threads) are waiting in a list
(every java object
can have a collection of threads waiting to be notified) and the event
would be the signal. So I don`t see the need to create java objects for
something that already is in the core of Java.
 
Let me explain where this NullWaiter is going to be part of. I need
something that can be compared to a ThreadPoolExecutor. But I don`t
want to execute a single job, but I want to execute a job by all
threads in that structure repeatedly (untill the task is set to null). I
have
called this structure the Repeater. The NullWaiter is going to be
part of the Repeater and contains the task all threads are waiting for.
If no task is available, all threads wait. But if a task is available,
they will keep repeating it..over.. and over.. and over.
 
Why do I need such a strange beast? It is going to be part
of a channels project I`m writing. One of the usages is that a
Repeater is going to 'suck' messages out of a channel.
 
example:
 
 public static void main(String[] args){
  Channel<FetchRequest> requestChannel = new
StdBufferedChannel<FetchRequest>(500);
  Channel<FetchResult> resultChannel = new
StdBufferedChannel<FetchResult>(50);
 
  RepeaterService fetchRepeater = new StdRepeaterService(5);//5 threads
  fetchRepeater.start();
  Fetcher fetcher = new
Fetcher(requestChannel,resultChannel,fetchRepeater);
 
  RepeaterService analyzeRepeater = new StdRepeaterService(1);//1 thread
  analyzeRepeater.start();
  Analyzer analyzer = new
Analyzer(resultChannel,requestChannel,analyzerExecutor);
 
  try {
       requestChannel.put(new FetchRequest(new
URL("http://dmoz.org/")));
  } catch (InterruptedException e) {
   e.printStackTrace();
  } catch (MalformedURLException e) {
   e.printStackTrace();
  }
 }
 
 
 
 



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

AW: Waiting for object value to be available.

Ernst, Matthias
In reply to this post by Peter Veentjer - Anchor Men
Interesting challenge, actually.

Tim's SimpleAvaitableValue does it, yet I was hoping to find a simple
lock-free version that avoids "lock-getValue-unlock"-sequence in the
common case (value != null) and requires only a volatile read.

So I thought, "AbstractQueuedSynchronizer implements all the queueing,
you just have to model the state transitions", and tried to morph AQS by
changing the state type from 'int' to 'Object'.

This proved more complicated than I had expected :-)

Is this a case for separating the queueing functionality from the
integer state and the notion of shared/exclusive?

Matthias

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Waiting for object value to be available.

tpeierls
In reply to this post by Peter Veentjer - Anchor Men
Peter Veentjer - Anchor Men wrote:

> I allready had removed the read write lock ...
>  
> public class Bar<E> {
>  private final ReentrantLock _lock;
>  private volatile E _item;
>  private final Condition _availableCond;
>  public Bar(boolean fair){
>   _lock = new ReentrantLock(fair);
>   _availableCond = _lock.newCondition();
>  }
>  public E get() throws InterruptedException {
>   _lock.lockInterruptibly();
>   try{
>    while(_item == null)
>     _availableCond.wait();
>    return _item;
>   }finally{
>    _lock.unlock();
>   }
>  }
>  public void set(E item) throws InterruptedException {
>   _lock.lockInterruptibly();
>   try{
>    _item = item;
>    if(_item!=null)
>     _availableCond.signalAll();
>   }finally{
>    _lock.unlock();
>   }
>  }
> }

Your version doesn't take advantage of the volatility of _item. You should
either remove the volatile keyword or add these lines to the top of your get()
implementation:

     E item = _item;
     if (item != null) return item;

Also, do you have any experimental evidence to suggest that the Lock will ever
need to be fair? It seems unlikely to me, especially if you add the volatile
optimization above, where readers don't even block when there's a non-null value.

And since there won't be much blocking, there won't be much lock contention,
so you don't really need to use ReentrantLock at all. Stick with intrinsic
locking, as in the SimpleAwaitableValue code I posted.

ReentrantLock is appropriate when you need a feature that it provides that
intrinsic locking doesn't or when you expect a *lot* of contention. Otherwise,
intrinsic locking is easier to read and likely to perform just as well, if not
better.


> But I`m going to need the read write lock. I don`t want multiple
> values of the WaitableValue out there.. only one is allowed
> (I only want one task-instance running, not two).. So I`m going
> to use the read write lock to garantuee that all old values
> are returned before a new value is available.

Using RWL doesn't prevent two readers from seeing different values if there is
an intervening write, so I don't think you need it.

--tim

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Waiting for object value to be available.

Doug Lea
In reply to this post by Shaffer, Darron
Shaffer, Darron wrote:
> The old WaitableReference class would do this nicely.  Unfortunately, it
> didn't make it into Java 5.
>
> By the way, why didn't this group of classes end up in Java 5?
>

This was a "doesn't-carry-its-weight" judgement. It would have entailed
putting out specs, inmplementations, and TCK tests for up to eighteen
little classes that are rarely used (especially considering overlap
with the AtomicX classes, which were sorely needed) and not too
hard for people to make themselves when they need them.

Someday I ought to make good on intent to separately release new
J2SE5-compatible versions of the little things in dl.util.concurrent
that didn't make it into java.util.concurrent. But too many other things
always seem to have higher priority. (Maybe someone on this list
would like to take this on?)

-Doug

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: AW: Waiting for object value to be available.

Doug Lea
In reply to this post by Ernst, Matthias
Ernst, Matthias wrote:
>
> Tim's SimpleAvaitableValue does it, yet I was hoping to find a simple
> lock-free version that avoids "lock-getValue-unlock"-sequence in the
> common case (value != null) and requires only a volatile read.

(Not sure I understand. Tim's does that bypass, at the expense only
of a recheck, which is likely to be about as fast as anything else.)

>
> So I thought, "AbstractQueuedSynchronizer implements all the queueing,
> you just have to model the state transitions", and tried to morph AQS by
> changing the state type from 'int' to 'Object'.

I can't think of a really good reason to want to do this. Why not use
integer codes for null/nonull and then another Object field for data?
Like Tim though, my guess is that even this is excessive compared to
Tim's version unless it is a performance bottleneck.

>
> This proved more complicated than I had expected :-)
>
> Is this a case for separating the queueing functionality from the
> integer state and the notion of shared/exclusive?

Among the challenges in doing this would be to give some handle to
synchronizer implementors for avoiding garbage retention stemming
from references inside AQS nodes. Lack of good ideas about this
and related issues led us to add "Long" version of AQS to Mustang
but not "Reference" version.


-Doug

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Waiting for object value to be available.

Peter Veentjer - Anchor Men
In reply to this post by Peter Veentjer - Anchor Men
Your version doesn't take advantage of the volatility of _item.
--------------------
What is there to take advantage of (I guess I`m missing something)?
And I would rather make something that is less efficient but a lot clearer.
 So if mine doesn`t work.. I`ll change it, but if it does, I won`t change it
(it would be to difficult to understand).

Also, do you have any experimental evidence to suggest that the Lock will ever
need to be fair? It seems unlikely to me, especially if you add the volatile
optimization above, where readers don't even block when there's a non-null value.

And since there won't be much blocking, there won't be much lock contention,
so you don't really need to use ReentrantLock at all. Stick with intrinsic
locking, as in the SimpleAwaitableValue code I posted.

ReentrantLock is appropriate when you need a feature that it provides that
intrinsic locking doesn't or when you expect a *lot* of contention. Otherwise,
intrinsic locking is easier to read and likely to perform just as well, if not
better.
--------------------------------
You have lost me here. I`m not a concurrency master, so I would rather have something
that I understand and works... than something that maybe works better/efficient but I can`t
understand.
 

Using RWL doesn't prevent two readers from seeing different values if there is
an intervening write, so I don't think you need it.
---------------------------------------------
With a RWL this behaviour can be realised. If every readed returns the read value (so unlocks a readlock)
only a write lock can be optained of all readers have unlocked.

--tim




_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Waiting for object value to be available.

Peter Veentjer - Anchor Men
In reply to this post by Peter Veentjer - Anchor Men
Your version doesn't take advantage of the volatility of _item.
------------------------------------
Btw: If I don`t add the volatile keyword, the item in the while loop could be a cached value and that value could never update. So or something has changed in Java (and Java has changed their memory/concurrency model), or I`m missing something.. (or you made a mistake).
 
the code:
 
  public E get() throws InterruptedException {
>   _lock.lockInterruptibly();
>   try{
>    while(_item == null)
>     _availableCond.wait();
>    return _item;
>   }finally{
>    _lock.unlock();
>   }
>  }

 
It _item is not made volatile, the while loop could use some value stored in some kind of cpu-register that never gets updated. That is as far as I know of, the whole reason about the existence of the volatile keyword.
 
 
 
You should
either remove the volatile keyword or add these lines to the top of your get()
implementation:

     E item = _item;
     if (item != null) return item;

Also, do you have any experimental evidence to suggest that the Lock will ever
need to be fair? It seems unlikely to me, especially if you add the volatile
optimization above, where readers don't even block when there's a non-null value.

And since there won't be much blocking, there won't be much lock contention,
so you don't really need to use ReentrantLock at all. Stick with intrinsic
locking, as in the SimpleAwaitableValue code I posted.

ReentrantLock is appropriate when you need a feature that it provides that
intrinsic locking doesn't or when you expect a *lot* of contention. Otherwise,
intrinsic locking is easier to read and likely to perform just as well, if not
better.


> But I`m going to need the read write lock. I don`t want multiple
> values of the WaitableValue out there.. only one is allowed
> (I only want one task-instance running, not two).. So I`m going
> to use the read write lock to garantuee that all old values
> are returned before a new value is available.

Using RWL doesn't prevent two readers from seeing different values if there is
an intervening write, so I don't think you need it.

--tim




_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Waiting for object value to be available.

Joe Bowbeer
In reply to this post by Peter Veentjer - Anchor Men
I suggest a custom Future implementation or a custom BlockingQueueimplementation.
As others have pointed out, Future provides the desired get() orget(timeout) API for the reading client.
Similary, BlockingQueue provides poll() and poll(timeout).
In terms of implementation, these approaches resolve to eithercreating a resetable FutureTask or employing a single-entryBlockingQueue (where the writing client would first take the onlyelement from the queue and then put a new element).
I suggest the latter.  You can repackage the API to hide theBlockingQueue details from the user, but the details would look like:
queue = new ArrayBlockingQueue<E>(1);
// readers
E = queue.poll(timeout, unit);
// writer
queue.clear();queue.put(E);

Joe.


On 8/23/05, Peter Veentjer - Anchor Men <[hidden email]> wrote:>  >   >  >   > I have the following problem. >   > I want some kind of container that can store an object. Multiple threads can> read a value from that container, and if there is no object available (the> value is null) they are going to sleep (or sleep untill a timeout occurs).> If there is a value available, all threads that where sleeping wake up.. and> read the value (but don`t remove it like a in blockingqueue) >   > The problem: > -A good name for such a structure. At the moment I have NotNullWaiter, but> well.. that sucks. > -I want to know if there exist something like it. >   > And I would like it if you would have a look at my code. >   > public class NotNullWaiter<E> { >   >  private final ReadWriteLock _lock;>  private final Condition _itemAvailable;>  private volatile E _item; >   >  public NotNullWaiter(){>   this(false);>  } >   >  public NotNullWaiter(boolean fair){>   _lock = new ReentrantReadWriteLock(fair);>   _itemAvailable = _lock.writeLock().newCondition();>  } >   >  public E read()throws InterruptedException{>   _lock.readLock().lockInterruptibly(); >   >   try{>    while(_item==null)>     _itemAvailable.wait(); >   >    return _item;>   }finally{>    _lock.readLock().unlock();>   }>  } >   >  public E read(long timeout, TimeUnit timeUnit)throws InterruptedException{>   if(timeUnit == null)throw new NullPointerException(); >   >   _lock.readLock().lockInterruptibly(); >   >   try{>    long nanos = timeUnit.toNanos(timeout);>    for (;;) {>     //if there is an item available, return it.>     if (_item !=null)>      return _item; >   >     //if the time has passed, return null to indicate no item is available.>     if (nanos <= 0)>      return null; >   >     try {>      nanos = _itemAvailable.awaitNanos(nanos);>     } catch (InterruptedException ie) {>      _itemAvailable.signal(); // propagate to non-interrupted thread (todo:> why???)>      throw ie;>     }>    }>   }finally{>    _lock.readLock().unlock();>   }>  } >   >  public void write(E item)throws InterruptedException{>      _lock.writeLock().lockInterruptibly(); >   >   try{>    _item = item;>    if(item != null)>     _itemAvailable.signalAll();>   }finally{>    _lock.writeLock().unlock();>   }>  } >   >  /*>  private void write(E e, long timeout, TimeUnit timeUnit)throws> InterruptedException{>     if(timeUnit == null)throw new NullPointerException(); >   >   _lock.writeLock().lockInterruptibly();>   try{>       long nanos = timeUnit.toNanos(timeout);>             for (;;) { >   >    }>   }finally{>    _lock.writeLock().unlock();>   }>  } */> }>  >  > > Met vriendelijke groet,> > Peter Veentjer> Anchor Men Interactive Solutions – duidelijk in zakelijke> internetoplossingen> > Praediniussingel 41> 9711 AE Groningen> > T: 050-3115222> F: 050-5891696> E: [hidden email]> I : www.anchormen.nl >   >  > > Met vriendelijke groet,> > Peter Veentjer> Anchor Men Interactive Solutions – duidelijk in zakelijke> internetoplossingen> > Praediniussingel 41> 9711 AE Groningen> > T: 050-3115222> F: 050-5891696> E: [hidden email]> I : www.anchormen.nl >   > _______________________________________________> Concurrency-interest mailing list> [hidden email]> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest> > >
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Waiting for object value to be available.

Joe Bowbeer
Oops.  Scratch the ArrayBlockingQueue idea.  poll is not peek and vice versa..

I still think the BlockingQueue interface is a reasonable model, but
you'd need a custom implementation.

Back to resettable Future then.


On 8/23/05, Joe Bowbeer <[hidden email]> wrote:

> I suggest a custom Future implementation or a custom BlockingQueue
> implementation.
>
> As others have pointed out, Future provides the desired get() or
> get(timeout) API for the reading client.
>
> Similary, BlockingQueue provides poll() and poll(timeout).
>
> In terms of implementation, these approaches resolve to either
> creating a resetable FutureTask or employing a single-entry
> BlockingQueue (where the writing client would first take the only
> element from the queue and then put a new element).
>
> I suggest the latter.  You can repackage the API to hide the
> BlockingQueue details from the user, but the details would look like:
>
> queue = new ArrayBlockingQueue<E>(1);
>
> // readers
>
> E = queue.poll(timeout, unit);
>
> // writer
>
> queue.clear();
> queue.put(E);
>
>
> Joe.
>
>
>
> On 8/23/05, Peter Veentjer - Anchor Men <[hidden email]> wrote:
> >
> >
> >
> >
> > I have the following problem.
> >
> > I want some kind of container that can store an object. Multiple threads can
> > read a value from that container, and if there is no object available (the
> > value is null) they are going to sleep (or sleep untill a timeout occurs).
> > If there is a value available, all threads that where sleeping wake up.. and
> > read the value (but don`t remove it like a in blockingqueue)
> >
> > The problem:
> > -A good name for such a structure. At the moment I have NotNullWaiter, but
> > well.. that sucks.
> > -I want to know if there exist something like it.
> >
> > And I would like it if you would have a look at my code.
> >
> > public class NotNullWaiter<E> {
> >
> >  private final ReadWriteLock _lock;
> >  private final Condition _itemAvailable;
> >  private volatile E _item;
> >
> >  public NotNullWaiter(){
> >   this(false);
> >  }
> >
> >  public NotNullWaiter(boolean fair){
> >   _lock = new ReentrantReadWriteLock(fair);
> >   _itemAvailable = _lock.writeLock().newCondition();
> >  }
> >
> >  public E read()throws InterruptedException{
> >   _lock.readLock().lockInterruptibly();
> >
> >   try{
> >    while(_item==null)
> >     _itemAvailable.wait();
> >
> >    return _item;
> >   }finally{
> >    _lock.readLock().unlock();
> >   }
> >  }
> >
> >  public E read(long timeout, TimeUnit timeUnit)throws InterruptedException{
> >   if(timeUnit == null)throw new NullPointerException();
> >
> >   _lock.readLock().lockInterruptibly();
> >
> >   try{
> >    long nanos = timeUnit.toNanos(timeout);
> >    for (;;) {
> >     //if there is an item available, return it.
> >     if (_item !=null)
> >      return _item;
> >
> >     //if the time has passed, return null to indicate no item is available.
> >     if (nanos <= 0)
> >      return null;
> >
> >     try {
> >      nanos = _itemAvailable.awaitNanos(nanos);
> >     } catch (InterruptedException ie) {
> >      _itemAvailable.signal(); // propagate to non-interrupted thread (todo:
> > why???)
> >      throw ie;
> >     }
> >    }
> >   }finally{
> >    _lock.readLock().unlock();
> >   }
> >  }
> >
> >  public void write(E item)throws InterruptedException{
> >      _lock.writeLock().lockInterruptibly();
> >
> >   try{
> >    _item = item;
> >    if(item != null)
> >     _itemAvailable.signalAll();
> >   }finally{
> >    _lock.writeLock().unlock();
> >   }
> >  }
> >
> >  /*
> >  private void write(E e, long timeout, TimeUnit timeUnit)throws
> > InterruptedException{
> >     if(timeUnit == null)throw new NullPointerException();
> >
> >   _lock.writeLock().lockInterruptibly();
> >   try{
> >       long nanos = timeUnit.toNanos(timeout);
> >             for (;;) {
> >
> >    }
> >   }finally{
> >    _lock.writeLock().unlock();
> >   }
> >  } */
> > }
> >

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Waiting for object value to be available.

David Holmes
In reply to this post by Peter Veentjer - Anchor Men
Being in a different time-zone gives me the advantage of seeing the story
unwind so that all the requirements are extracted.

>From what I read Peter wants a "waitable reference" as has been discussed,
which is very much like a settable FutureTask. *However* the part that I
don't think people have picked up on yet is the use of the ReadWriteLock. If
I understand Peter correctly, the intent is that the value of the object
can't be changed while anybody is using that value - which in this case
means a thread is running that task. So the intent then is that the getter
will do something like:

    readLock.acquire();
    try {
       V val = value.get();
       process(val);
    }
    finally {
      readLock.release();
    }

However the code that Peter originally showed does not do this. It simply
held the readLock while doing the get() and returning the value. Hence as
soon as the value was returned and the readLock released then the value
could be changed and two (or more) different versions of the task could be
being processed.

So the interface that I see for this is more like:

    E acquireValue();
    void releaseValue(E val);
    void setValue(E val);

and so the client of this would do:

    E val = value.acquireValue();
    try {
        process(val);
    }
    finally {
       value.releaseValue(val);
    }

The intent being that if the number of successful acquires exceed the number
of successful releases then the current value is being used and so setValue
will block.

Does this represent what you want to do Peter? If so we can pursue
implementation approaches.


A couple of additional notes. In the original code you have:

  public E read()throws InterruptedException{
    _lock.readLock().lockInterruptibly();
     try{
       while(_item==null)
            _itemAvailable.wait();

You can't do this. The Condition is associated with the WriteLock and to
wait on it you must hold the WriteLock. To fix this per acquireValue above
you would do:

    writeLock.lockInterruptibly();
    try {
       while(item == null)
             itemAvailable.await();  // NOTE await NOT Object.wait
       readLock.lock(); //  writer can acquire readLock to downgrade
       return item;
    }
    finally {
       writeLock.unlock();
    }

and in releaseValue() you would do the readLock.unlock(). Of course you need
to take great care in the client code to ensure the releaseValue() is always
called even if the client throws an exception etc.


Second issue: volatile. You only need to use volatile if you will access a
shared mutable variable without using any other form of synchronization.
Other forms of synchronization include always accessing the variable with
the same lock held (or for ReadWrite locks a read-lock or write-lock from
the same ReadWriteLock); or correctly using atomic variables or other
volatile variables that protect/coordinate access to the variable concerned.
In your code you always access _item with a lock held, so it need not be
volatile. The use of Locks provides all the necessary memory model
guarantees that ensures that all updates are visible where they need to be.

Tim's point was that you could use the volatility of item to do a safe
fast-path through the code, for the case where item is not null, to avoid
the need for acquiring a lock ie it would be a performance boost. That
comment doesn't account for the "nobody can set while the value is being
used" semantics that I think you want, however.

I hope this helps.

Cheers,
David Holmes

PS. Please try and use a mail program that correctly indents or prefixes
text written by others - it is vary hard to see in your mails what comments
are from you and what are quoted from other posters. Thanks.

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest