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
     1 package org.apidesign.reentrant;
     2 
     3 import java.util.Collection;
     4 import java.util.concurrent.atomic.AtomicInteger;
     5 
     6 public class CriticalSectionReentrantImmutable<T extends Comparable<T>> implements CriticalSection<T> {
     7     private ImmutableData<T> data = new ImmutableData<T>();
     8     
     9     public void assignPilot(T pilot) {
    10         data = data.newPilot(pilot);
    11     }
    12 
    13     // BEGIN: reentrant.merge.immutable
    14     public int sumBigger(Collection<T> args) {
    15         for (;;) {
    16             ImmutableData<T> previous;
    17             synchronized (this) {
    18                 previous = this.data;
    19             }
    20             int[] ret = { 0 };
    21             ImmutableData<T> now = doCriticalSection(args, previous, ret);
    22             
    23             synchronized (this) {
    24                 // if there was no parallel or reentrant change, 
    25                 // apply and return. Otherwise try once more.
    26                 if (previous == this.data) {
    27                     this.data = now;
    28                     return ret[0];
    29                 }
    30             }
    31         }
    32     }
    33     // END: reentrant.merge.immutable
    34     
    35     private ImmutableData<T> doCriticalSection(Collection<T> args, ImmutableData<T> data, int[] result) {
    36         result[0] = 0;
    37         for (T cmp : args) {
    38             if (data.pilot.compareTo(cmp) < 0) {
    39                 result[0]++;
    40             }
    41         }
    42         return data.newCnt(data.cnt + result[0]);
    43     }
    44 
    45     public int getCount() {
    46         return data.cnt;
    47     }
    48     
    49     private static final class ImmutableData<T> {
    50         final T pilot;
    51         final int cnt;
    52         
    53         public ImmutableData() {
    54             pilot = null;
    55             cnt = 0;
    56         }
    57         private ImmutableData(T pilot, int cnt) {
    58             this.pilot = pilot;
    59             this.cnt = cnt;
    60         }
    61         
    62         public ImmutableData<T> newPilot(T pilot) {
    63             return new ImmutableData(pilot, this.cnt);
    64         }
    65         public ImmutableData<T> newCnt(int cnt) {
    66             return new ImmutableData(this.pilot, cnt);
    67         }
    68     }
    69 }