/** AWK~plus - Atomic-2.
 */
# クロージャとコンカレント・ロック使った方法を思いつきました(普通のユーザー関数をコンカレント・ロック化できます)
# I came up with a way to use closures and concurrent locks.
# (You can concurrent lock ordinary user functions)
    val number = 100
    val multi = 8 # スレッドの多重度(Thread multiplicity)
    val guard = Barrier(multi) # バリア(Barrier)
    var count = 0
    var total = 0
BEGIN {
    val T = new AtomicArray() # AtomicMap でも OK.
    printf ".'count' %s 'total' %s\n", count.getClass(), total.getClass()
    for (var i = 0; multi > i; ++i)
        T[i] = Future(.party(i + 1)) # スレッドを作成して、パーティに参加(Join a party)
    Join(T) # パーティ終了を待ち合わせる(Wait for the end of the party)
    printf "\n.'count' %s 'total' %s\n", count.getClass(), total.getClass()
    printf ". atomic (%d) Expect: 5050 Actual: %d\n", multi, total
    assertEquals(5050, total, "!")
    print "."
}
function party(id: int) {
    function calc(x: Function) { return x.apply() } # 関数を間数値として呼び出すためのコンテナ.
    function increment() {
        if (number > count) { # ここで排他(Exclusive control here)
            total +=  ++count
            total = new AtomicNumber(total) # BUG? Groovy's measures against 'BigDecimal'.
        }
        # printf "(%d %d %d)", id, count, total
        return (number > count)
    }
    printf "(Join %d)", id
    Join(guard) # パーティの参加者が揃うのを待ち合わせる(Wait for party participants)
    while (calc(..increment())) { # 排他モード'..'で間数値を呼び出す.
    }
    printf "(end %d)", id
}