Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   *  Copyright (c) 2012 Jan Kotek
   *
   *  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.
  */
 
 /*
  * Adopted from Apache Harmony with following copyright:
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
  */
 package org.mapdb;

A small toolkit of classes that support lock-free thread-safe programming on single records. In essence, the classes here provide provide an atomic conditional update operation of the form:

   boolean compareAndSet(expectedValue, updateValue);
 

This method (which varies in argument types across different classes) atomically sets a record to the updateValue if it currently holds the expectedValue, reporting true on success. Classes jere also contain methods to get and unconditionally set values.

The specifications of these methods enable to employ more efficient internal DB locking. CompareAndSwap operation is typically faster than using transactions, global lock or other concurrent protection.

Instances of classes Atomic.Boolean, Atomic.Integer, Atomic.Long, Atomic.String and Atomic.Var each provide access and updates to a single record of the corresponding type. Each class also provides appropriate utility methods for that type. For example, classes Atomic.Long and Atomic.Integer provide atomic increment methods. One application is to generate unique keys for Maps:

    Atomic.Long id = Atomic.getLong("mapId");
    map.put(id.getAndIncrement(), "something");
 

Atomic classes are designed primarily as building blocks for implementing non-blocking data structures and related infrastructure classes. The compareAndSet method is not a general replacement for locking. It applies only when critical updates for an object are confined to a single record.

Atomic classes are not general purpose replacements for java.lang.Integer and related classes. They do not define methods such as hashCode and compareTo. (Because atomic records are expected to be mutated, they are poor choices for hash table keys.) Additionally, classes are provided only for those types that are commonly useful in intended applications. Other types has to be wrapped into general Atomic.Var

You can also hold floats using java.lang.Float.floatToIntBits(float) and java.lang.Float.intBitsToFloat(int) conversions, and doubles using java.lang.Double.doubleToLongBits(double) and java.lang.Double.longBitsToDouble(long) conversions.

 
 final public class Atomic {
 
     private Atomic(){}


    
An int record that may be updated atomically. An Atomic@Integer is used in applications such as atomically incremented counters, and cannot be used as a replacement for an java.lang.Integer. However, this class does extend Number to allow uniform access by tools and utilities that deal with numerically-based classes.
 
     public final static class Integer extends Number {
 
		private static final long serialVersionUID = 4615119399830853054L;
		protected final Engine engine;
        protected final long recid;
        public Integer(Engine enginelong recid) {
            this. = engine;
            this. = recid;
        }

        
Gets the current value.

Returns:
the current value
        public final int get() {
            return .get(.);
        }

        
Sets to the given value.

Parameters:
newValue the new value
        public final void set(int newValue) {
            .update(newValue.);
        }


        
Atomically sets to the given value and returns the old value.

Parameters:
newValue the new value
Returns:
the previous value
        public final int getAndSet(int newValue) {
            for (;;) {
                int current = get();
                if (compareAndSet(currentnewValue))
                    return current;
            }
        }

        
Atomically sets the value to the given updated value if the current value == the expected value.

Parameters:
expect the expected value
update the new value
Returns:
true if successful. False return indicates that the actual value was not equal to the expected value.
        public final boolean compareAndSet(int expectint update) {
            return .compareAndSwap(expectupdate.);
        }


        
Atomically increments by one the current value.

Returns:
the previous value
        public final int getAndIncrement() {
            for (;;) {
                int current = get();
                int next = current + 1;
                if (compareAndSet(currentnext))
                    return current;
            }
        }

        
Atomically decrements by one the current value.

Returns:
the previous value
        public final int getAndDecrement() {
            for (;;) {
                int current = get();
                int next = current - 1;
                if (compareAndSet(currentnext))
                    return current;
            }
        }

        
Atomically adds the given value to the current value.

Parameters:
delta the value to add
Returns:
the previous value
        public final int getAndAdd(int delta) {
            for (;;) {
                int current = get();
                int next = current + delta;
                if (compareAndSet(currentnext))
                    return current;
            }
        }

        
Atomically increments by one the current value.

Returns:
the updated value
        public final int incrementAndGet() {
            for (;;) {
                int current = get();
                int next = current + 1;
                if (compareAndSet(currentnext))
                    return next;
            }
        }

        
Atomically decrements by one the current value.

Returns:
the updated value
        public final int decrementAndGet() {
            for (;;) {
                int current = get();
                int next = current - 1;
                if (compareAndSet(currentnext))
                    return next;
            }
        }

        
Atomically adds the given value to the current value.

Parameters:
delta the value to add
Returns:
the updated value
        public final int addAndGet(int delta) {
            for (;;) {
                int current = get();
                int next = current + delta;
                if (compareAndSet(currentnext))
                    return next;
            }
        }

        
Returns the String representation of the current value.

Returns:
the String representation of the current value.
        public java.lang.String toString() {
            return java.lang.Integer.toString(get());
        }
        public int intValue() {
            return get();
        }
        public long longValue() {
            return (long)get();
        }
        public float floatValue() {
            return (float)get();
        }
        public double doubleValue() {
            return (double)get();
        }
    }


    
A long record that may be updated atomically. An Atomic#Long is used in applications such as atomically incremented sequence numbers, and cannot be used as a replacement for a java.lang.Long. However, this class does extend Number to allow uniform access by tools and utilities that deal with numerically-based classes.
    public final static class Long extends Number{
		private static final long serialVersionUID = 2882620413591274781L;
		protected final Engine engine;
        protected final long recid;
        public Long(Engine enginelong recid) {
            this. = engine;
            this. = recid;
        }


        
Gets the current value.

Returns:
the current value
        public final long get() {
            return .get(.);
        }

        
Sets to the given value.

Parameters:
newValue the new value
        public final void set(long newValue) {
            .update(newValue.);
        }


        
Atomically sets to the given value and returns the old value.

Parameters:
newValue the new value
Returns:
the previous value
        public final long getAndSet(long newValue) {
            while (true) {
                long current = get();
                if (compareAndSet(currentnewValue))
                    return current;
            }
        }

        
Atomically sets the value to the given updated value if the current value == the expected value.

Parameters:
expect the expected value
update the new value
Returns:
true if successful. False return indicates that the actual value was not equal to the expected value.
        public final boolean compareAndSet(long expectlong update) {
            return .compareAndSwap(expectupdate.);
        }


        
Atomically increments by one the current value.

Returns:
the previous value
        public final long getAndIncrement() {
            while (true) {
                long current = get();
                long next = current + 1;
                if (compareAndSet(currentnext))
                    return current;
            }
        }

        
Atomically decrements by one the current value.

Returns:
the previous value
        public final long getAndDecrement() {
            while (true) {
                long current = get();
                long next = current - 1;
                if (compareAndSet(currentnext))
                    return current;
            }
        }

        
Atomically adds the given value to the current value.

Parameters:
delta the value to add
Returns:
the previous value
        public final long getAndAdd(long delta) {
            while (true) {
                long current = get();
                long next = current + delta;
                if (compareAndSet(currentnext))
                    return current;
            }
        }

        
Atomically increments by one the current value.

Returns:
the updated value
        public final long incrementAndGet() {
            for (;;) {
                long current = get();
                long next = current + 1;
                if (compareAndSet(currentnext))
                    return next;
            }
        }

        
Atomically decrements by one the current value.

Returns:
the updated value
        public final long decrementAndGet() {
            for (;;) {
                long current = get();
                long next = current - 1;
                if (compareAndSet(currentnext))
                    return next;
            }
        }

        
Atomically adds the given value to the current value.

Parameters:
delta the value to add
Returns:
the updated value
        public final long addAndGet(long delta) {
            for (;;) {
                long current = get();
                long next = current + delta;
                if (compareAndSet(currentnext))
                    return next;
            }
        }

        
Returns the String representation of the current value.

Returns:
the String representation of the current value.
        public java.lang.String toString() {
            return java.lang.Long.toString(get());
        }
        public int intValue() {
            return (int)get();
        }
        public long longValue() {
            return get();
        }
        public float floatValue() {
            return (float)get();
        }
        public double doubleValue() {
            return (double)get();
        }
    }


    
A boolean record that may be updated atomically.
    public final static class Boolean {
        protected final Engine engine;
        protected final long recid;
        public Boolean(Engine enginelong recid) {
            this. = engine;
            this. = recid;
        }


        
Returns the current value.

Returns:
the current value
        public final boolean get() {
            return .get(.);
        }

        
Atomically sets the value to the given updated value if the current value == the expected value.

Parameters:
expect the expected value
update the new value
Returns:
true if successful. False return indicates that the actual value was not equal to the expected value.
        public final boolean compareAndSet(boolean expectboolean update) {
            return .compareAndSwap(expectupdate.);
        }


        
Unconditionally sets to the given value.

Parameters:
newValue the new value
        public final void set(boolean newValue) {
            .update(newValue.);
        }


        
Atomically sets to the given value and returns the previous value.

Parameters:
newValue the new value
Returns:
the previous value
        public final boolean getAndSet(boolean newValue) {
            for (;;) {
                boolean current = get();
                if (compareAndSet(currentnewValue))
                    return current;
            }
        }

        
Returns the String representation of the current value.

Returns:
the String representation of the current value.
        public java.lang.String toString() {
            return java.lang.Boolean.toString(get());
        }
    }

    
A String record that may be updated atomically.
    public final static class String{
        protected final Engine engine;
        protected final long recid;
        public String(Engine enginelong recid) {
            this. = engine;
            this. = recid;
        }
        public java.lang.String toString() {
            return get();
        }

        
Returns the current value.

Returns:
the current value
        public final java.lang.String get() {
            return .get(.);
        }

        
Atomically sets the value to the given updated value if the current value equals the expected value.

Parameters:
expect the expected value
update the new value
Returns:
true if successful. False return indicates that the actual value was not equal to the expected value.
        public final boolean compareAndSet(java.lang.String expectjava.lang.String update) {
            return .compareAndSwap(expectupdate.);
        }


        
Unconditionally sets to the given value.

Parameters:
newValue the new value
        public final void set(java.lang.String newValue) {
            .update(newValue.);
        }


        
Atomically sets to the given value and returns the previous value.

Parameters:
newValue the new value
Returns:
the previous value
        public final java.lang.String getAndSet(java.lang.String newValue) {
            for (;;) {
                java.lang.String current = get();
                if (compareAndSet(currentnewValue))
                    return current;
            }
        }
    }

    
Atomically updated variable which may contain any type of record.
    public static final class Var<E> {
        protected final Engine engine;
        protected final long recid;
        protected final Serializer<E> serializer;
        public Var(Engine enginelong recidSerializer<E> serializer) {
            this. = engine;
            this. = recid;
            this. = serializer;
        }
        public java.lang.String toString() {
            E v = get();
            return v==nullnull : v.toString();
        }

        
Returns the current value.

Returns:
the current value
        public final E get() {
            return .get();
        }

        
Atomically sets the value to the given updated value if the current value equals the expected value.

Parameters:
expect the expected value
update the new value
Returns:
true if successful. False return indicates that the actual value was not equal to the expected value.
        public final boolean compareAndSet(E expect, E update) {
            return .compareAndSwap(expectupdate);
        }


        
Unconditionally sets to the given value.

Parameters:
newValue the new value
        public final void set(E newValue) {
            .update(newValue);
        }


        
Atomically sets to the given value and returns the previous value.

Parameters:
newValue the new value
Returns:
the previous value
        public final E getAndSet(E newValue) {
            for (;;) {
                E current = get();
                if (compareAndSet(currentnewValue))
                    return current;
            }
        }
    }
New to GrepCode? Check out our FAQ X