samples/reentrant/src/org/apidesign/reentrant/CriticalSectionReentrantImmutable.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sat, 14 Jun 2008 10:04:53 +0200
changeset 210 acf2c31e22d4
parent 209 1c999569643b
permissions -rw-r--r--
Merge: Geertjan's changes to the end of the chapter
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@210
    16
            ImmutableData<T> previous;
jtulach@210
    17
            synchronized (this) {
jtulach@210
    18
                previous = this.data;
jtulach@210
    19
            }
jtulach@114
    20
            int[] ret = { 0 };
jtulach@114
    21
            ImmutableData<T> now = doCriticalSection(args, previous, ret);
jtulach@114
    22
            
jtulach@114
    23
            synchronized (this) {
jtulach@114
    24
                // if there was no parallel or reentrant change, 
jtulach@114
    25
                // apply and return. Otherwise try once more.
jtulach@114
    26
                if (previous == this.data) {
jtulach@114
    27
                    this.data = now;
jtulach@114
    28
                    return ret[0];
jtulach@114
    29
                }
jtulach@114
    30
            }
jtulach@114
    31
        }
jtulach@114
    32
    }
jtulach@114
    33
    // END: reentrant.merge.immutable
jtulach@114
    34
    
jtulach@114
    35
    private ImmutableData<T> doCriticalSection(Collection<T> args, ImmutableData<T> data, int[] result) {
jtulach@114
    36
        result[0] = 0;
jtulach@114
    37
        for (T cmp : args) {
jtulach@114
    38
            if (data.pilot.compareTo(cmp) < 0) {
jtulach@114
    39
                result[0]++;
jtulach@114
    40
            }
jtulach@114
    41
        }
jtulach@114
    42
        return data.newCnt(data.cnt + result[0]);
jtulach@114
    43
    }
jtulach@114
    44
jtulach@114
    45
    public int getCount() {
jtulach@114
    46
        return data.cnt;
jtulach@114
    47
    }
jtulach@114
    48
    
jtulach@114
    49
    private static final class ImmutableData<T> {
jtulach@114
    50
        final T pilot;
jtulach@114
    51
        final int cnt;
jtulach@114
    52
        
jtulach@114
    53
        public ImmutableData() {
jtulach@114
    54
            pilot = null;
jtulach@114
    55
            cnt = 0;
jtulach@114
    56
        }
jtulach@114
    57
        private ImmutableData(T pilot, int cnt) {
jtulach@114
    58
            this.pilot = pilot;
jtulach@114
    59
            this.cnt = cnt;
jtulach@114
    60
        }
jtulach@114
    61
        
jtulach@114
    62
        public ImmutableData<T> newPilot(T pilot) {
jtulach@114
    63
            return new ImmutableData(pilot, this.cnt);
jtulach@114
    64
        }
jtulach@114
    65
        public ImmutableData<T> newCnt(int cnt) {
jtulach@114
    66
            return new ImmutableData(this.pilot, cnt);
jtulach@114
    67
        }
jtulach@114
    68
    }
jtulach@114
    69
}