class Buckets { def cells = [] final n Buckets(n, limit=1000, random=new Random()) { this.n = n (0.. synchronized(buckets) { def targetDiff = (buckets[i]-buckets[j]).intdiv(2) if (targetDiff < 0) { buckets.transfer(j, i, -targetDiff) } else { buckets.transfer(i, j, targetDiff) } } } def randomize = { i, j -> synchronized(buckets) { def targetLimit = buckets[i] + buckets[j] def targetI = random.nextInt(targetLimit + 1) if (targetI < buckets[i]) { buckets.transfer(i, j, buckets[i] - targetI) } else { buckets.transfer(j, i, targetI - buckets[i]) } } } Thread.start { def start = System.currentTimeMillis() while (start + 10000 > System.currentTimeMillis()) { def i = random.nextInt(buckets.n) def j = random.nextInt(buckets.n) makeCloser(i, j) } } Thread.start { def start = System.currentTimeMillis() while (start + 10000 > System.currentTimeMillis()) { def i = random.nextInt(buckets.n) def j = random.nextInt(buckets.n) randomize(i, j) } } def start = System.currentTimeMillis() while (start + 10000 > System.currentTimeMillis()) { synchronized(buckets) { def sum = buckets.cells.sum() println "${new Date()}: checksum: ${sum} buckets: ${buckets}" } Thread.sleep(500) }