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
     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 = this.data;
    17             int[] ret = { 0 };
    18             ImmutableData<T> now = doCriticalSection(args, previous, ret);
    19             
    20             synchronized (this) {
    21                 // if there was no parallel or reentrant change, 
    22                 // apply and return. Otherwise try once more.
    23                 if (previous == this.data) {
    24                     this.data = now;
    25                     return ret[0];
    26                 }
    27             }
    28         }
    29     }
    30     // END: reentrant.merge.immutable
    31     
    32     private ImmutableData<T> doCriticalSection(Collection<T> args, ImmutableData<T> data, int[] result) {
    33         result[0] = 0;
    34         for (T cmp : args) {
    35             if (data.pilot.compareTo(cmp) < 0) {
    36                 result[0]++;
    37             }
    38         }
    39         return data.newCnt(data.cnt + result[0]);
    40     }
    41 
    42     public int getCount() {
    43         return data.cnt;
    44     }
    45     
    46     private static final class ImmutableData<T> {
    47         final T pilot;
    48         final int cnt;
    49         
    50         public ImmutableData() {
    51             pilot = null;
    52             cnt = 0;
    53         }
    54         private ImmutableData(T pilot, int cnt) {
    55             this.pilot = pilot;
    56             this.cnt = cnt;
    57         }
    58         
    59         public ImmutableData<T> newPilot(T pilot) {
    60             return new ImmutableData(pilot, this.cnt);
    61         }
    62         public ImmutableData<T> newCnt(int cnt) {
    63             return new ImmutableData(this.pilot, cnt);
    64         }
    65     }
    66 }