samples/reentrant/src/org/apidesign/reentrant/CriticalSectionReentrantImmutable.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sat, 14 Jun 2008 09:54:39 +0200
changeset 114 c479228609ea
child 204 bd5089d23771
permissions -rw-r--r--
Part II: Practical Design is now ready for review by our reviewers
jtulach@114
     1
package org.apidesign.reentrant;
jtulach@114
     2
jtulach@114
     3
import java.util.Collection;
jtulach@114
     4
import java.util.concurrent.atomic.AtomicInteger;
jtulach@114
     5
jtulach@114
     6
public class CriticalSectionReentrantImmutable<T extends Comparable<T>> implements CriticalSection<T> {
jtulach@114
     7
    private ImmutableData<T> data = new ImmutableData<T>();
jtulach@114
     8
    
jtulach@114
     9
    public void assignPilot(T pilot) {
jtulach@114
    10
        data = data.newPilot(pilot);
jtulach@114
    11
    }
jtulach@114
    12
jtulach@114
    13
    // BEGIN: reentrant.merge.immutable
jtulach@114
    14
    public int sumBigger(Collection<T> args) {
jtulach@114
    15
        for (;;) {
jtulach@114
    16
            ImmutableData<T> previous = this.data;
jtulach@114
    17
            int[] ret = { 0 };
jtulach@114
    18
            ImmutableData<T> now = doCriticalSection(args, previous, ret);
jtulach@114
    19
            
jtulach@114
    20
            synchronized (this) {
jtulach@114
    21
                // if there was no parallel or reentrant change, 
jtulach@114
    22
                // apply and return. Otherwise try once more.
jtulach@114
    23
                if (previous == this.data) {
jtulach@114
    24
                    this.data = now;
jtulach@114
    25
                    return ret[0];
jtulach@114
    26
                }
jtulach@114
    27
            }
jtulach@114
    28
        }
jtulach@114
    29
    }
jtulach@114
    30
    // END: reentrant.merge.immutable
jtulach@114
    31
    
jtulach@114
    32
    private ImmutableData<T> doCriticalSection(Collection<T> args, ImmutableData<T> data, int[] result) {
jtulach@114
    33
        result[0] = 0;
jtulach@114
    34
        for (T cmp : args) {
jtulach@114
    35
            if (data.pilot.compareTo(cmp) < 0) {
jtulach@114
    36
                result[0]++;
jtulach@114
    37
            }
jtulach@114
    38
        }
jtulach@114
    39
        return data.newCnt(data.cnt + result[0]);
jtulach@114
    40
    }
jtulach@114
    41
jtulach@114
    42
    public int getCount() {
jtulach@114
    43
        return data.cnt;
jtulach@114
    44
    }
jtulach@114
    45
    
jtulach@114
    46
    private static final class ImmutableData<T> {
jtulach@114
    47
        final T pilot;
jtulach@114
    48
        final int cnt;
jtulach@114
    49
        
jtulach@114
    50
        public ImmutableData() {
jtulach@114
    51
            pilot = null;
jtulach@114
    52
            cnt = 0;
jtulach@114
    53
        }
jtulach@114
    54
        private ImmutableData(T pilot, int cnt) {
jtulach@114
    55
            this.pilot = pilot;
jtulach@114
    56
            this.cnt = cnt;
jtulach@114
    57
        }
jtulach@114
    58
        
jtulach@114
    59
        public ImmutableData<T> newPilot(T pilot) {
jtulach@114
    60
            return new ImmutableData(pilot, this.cnt);
jtulach@114
    61
        }
jtulach@114
    62
        public ImmutableData<T> newCnt(int cnt) {
jtulach@114
    63
            return new ImmutableData(this.pilot, cnt);
jtulach@114
    64
        }
jtulach@114
    65
    }
jtulach@114
    66
}