[concurrency-interest] Scalable object cache

√iktor Ҡlang viktor.klang at gmail.com
Wed Feb 29 09:39:43 EST 2012


Sooo, you're saying that toString, hashCode and equals will only ever be
called by the Thread that calls get()?

On Wed, Feb 29, 2012 at 2:37 PM, Peter Firmstone <
peter.firmstone at zeus.net.au> wrote:

> I don't have the hardware to test this so I'm hoping someone on the list
> will know.
>
> In the class below, the get() method returns the referent, provided it
> hasn't been enqueued.
>
> Both read and clock are volatile, clock is written to, once every 10
> seconds (or an interval the developer sets) by a single thread.
>
> if (read < clock) read = clock; //Avoid unnecessary volatile write.
>
> If many threads are retrieving the referent, the volatile read variable
> is written at least once in between clock updates, but any further
> retrievals will only be reads.
>
> So in this case the volatile long values are multi read, with occasional
> writes, does get() look scalable to you?
>
> Regards,
>
> Peter.
>
> /*
>  * Copyright 2012 Zeus Project Services Pty Ltd.
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
>  * You may obtain a copy of the License at
>  *
>  *      http://www.apache.org/licenses/LICENSE-2.0
>  *
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  */
> package au.net.zeus.collection;
>
> /**
>  *
>  * @author Peter Firmstone.
>  */
> class TimedReferrer<T> implements Referrer<T>, TimeBomb {
>
>    private volatile long clock;
>    private volatile long read;
>    private final TimedRefQueue queue;
>    private volatile T referent;
>    private volatile boolean enqued;
>    private final Object lock;
>    private final int hash;
>
>    TimedReferrer(T k, TimedRefQueue q){
>        long time = System.nanoTime();
>        clock = time;
>        read = time;
>        referent = k;
>        queue = q;
>        enqued = false;
>        lock = new Object();
>        int hash = 7;
>        hash = 29 * hash + k.hashCode();
>        hash = 29 * hash + k.getClass().hashCode();
>        this.hash = hash;
>    }
>
>    public T get() {
>        // Doesn't need to be atomic.
>        if (read < clock) read = clock; //Avoid unnecessary volatile
> write.
>        return referent;
>    }
>
>    public void clear() {
>        referent = null;
>    }
>
>    public boolean isEnqueued() {
>        return enqued;
>    }
>
>    public boolean enqueue() {
>        if (enqued) return false;
>        if (referent == null) return false;
>        if (queue == null) return false;
>        synchronized (lock){ // Sync for atomic write of enqued.
>            if (enqued) return false;
>            enqued = queue.offer(this);
>        }
>        return enqued;
>    }
>
>    @Override
>    public void updateClock(long time){
>        if (read < clock) { // only write volatile if necessary.
>            enqueue();
>            clear();
>        } else {
>            clock = time;
>        }
>    }
>
>    @Override
>    public boolean equals(Object o) {
>        if (this == o)  return true; // Same reference.
>        if (!(o instanceof Referrer))  return false;
>        Object k1 = get();
>        Object k2 = ((Referrer) o).get();
>        if ( k1 != null && k1.equals(k2)) return true;
>        return ( k1 == null && k2 == null && hashCode() ==
> o.hashCode()); // Both objects were collected.
>    }
>
>    @Override
>    public int hashCode() {
>        Object k = get();
>        int hash = 7;
>        if (k != null) {
>            hash = 29 * hash + k.hashCode();
>            hash = 29 * hash + k.getClass().hashCode();
>        } else {
>            hash = this.hash;
>        }
>        return hash;
>    }
>
>    @Override
>    public String toString(){
>        Object s = get();
>        if (s != null) return s.toString();
>        return super.toString();
>    }
>
> }
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>



-- 
Viktor Klang

Akka Tech Lead
Typesafe <http://www.typesafe.com/> - The software stack for applications
that scale

Twitter: @viktorklang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120229/a3cd1293/attachment.html>


More information about the Concurrency-interest mailing list