author | Jaroslav Tulach <jtulach@netbeans.org> |
Sat, 14 Jun 2008 10:04:53 +0200 | |
changeset 210 | acf2c31e22d4 |
parent 209 | 1c999569643b |
permissions | -rw-r--r-- |
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 |
} |