Atomic updates: Difference between revisions

Added Kotlin
(Added Kotlin)
Line 1,975:
Current state of buckets: [32, 20, 82, 70, 54, 41, 87, 15, 15, 44, 82, 55, 17, 33, 87, 104]. Total in buckets: 838
Total transactions: 26751 (1639 unlocks per second).
</pre>
 
=={{header|Kotlin}}==
{{trans|Java}}
<lang scala>// version 1.2.0
 
import java.util.concurrent.ThreadLocalRandom
import kotlin.concurrent.thread
 
const val NUM_BUCKETS = 10
 
class Buckets(data: IntArray) {
private val data = data.copyOf()
 
operator fun get(index: Int) = synchronized(data) { data[index] }
 
fun transfer(srcIndex: Int, dstIndex: Int, amount: Int): Int {
if (amount < 0) {
throw IllegalArgumentException("Negative amount: $amount")
}
if (amount == 0) return 0
synchronized(data) {
var a = amount
if (data[srcIndex] - a < 0) a = data[srcIndex]
if (data[dstIndex] + a < 0) a = Int.MAX_VALUE - data[dstIndex]
if (a < 0) throw IllegalStateException()
data[srcIndex] -= a
data[dstIndex] += a
return a
}
}
 
val buckets get() = synchronized(data) { data.copyOf() }
 
fun transferRandomAmount() {
val rnd = ThreadLocalRandom.current()
while (true) {
val srcIndex = rnd.nextInt(NUM_BUCKETS)
val dstIndex = rnd.nextInt(NUM_BUCKETS)
val amount = rnd.nextInt() and Int.MAX_VALUE
transfer(srcIndex, dstIndex, amount)
}
}
 
fun equalize() {
val rnd = ThreadLocalRandom.current()
while (true) {
val srcIndex = rnd.nextInt(NUM_BUCKETS)
val dstIndex = rnd.nextInt(NUM_BUCKETS)
val amount = (this[srcIndex] - this[dstIndex]) / 2
if (amount >= 0) transfer(srcIndex, dstIndex, amount)
}
}
 
fun print() {
while (true) {
val nextPrintTime = System.currentTimeMillis() + 3000
while (true) {
val now = System.currentTimeMillis()
if (now >= nextPrintTime) break
try {
Thread.sleep(nextPrintTime - now)
}
catch (e: InterruptedException) {
return
}
}
val bucketValues = buckets
println("Current values: ${bucketValues.total} ${bucketValues.asList()}")
}
}
}
 
val IntArray.total: Long get() {
var sum = 0L
for (d in this) sum += d
return sum
}
 
fun main(args: Array<String>) {
val rnd = ThreadLocalRandom.current()
val values = IntArray(NUM_BUCKETS) { rnd.nextInt() and Int.MAX_VALUE }
println("Initial array: ${values.total} ${values.asList()}")
val buckets = Buckets(values)
thread(name = "equalizer") { buckets.equalize() }
thread(name = "transferrer") { buckets.transferRandomAmount() }
thread(name = "printer") { buckets.print() }
}</lang>
 
Sample output:
<pre>
Initial array: 9412276676 [1252597313, 1908616225, 824662669, 972947315, 2126883821, 405179067, 693458796, 481375538, 396750085, 349805847]
Current values: 9412276676 [2147483647, 844064584, 983174119, 580879514, 1073741823, 666808378, 2147483647, 0, 484320482, 484320482]
Current values: 9412276676 [941221423, 941207347, 941304553, 941221422, 941235585, 941235585, 941225242, 941242321, 941157955, 941225243]
Current values: 9412276676 [941656114, 941197476, 941190372, 941203044, 941187119, 941177701, 941208610, 941038975, 941226893, 941190372]
Current values: 9412276676 [0, 202110459, 2147483647, 1901203310, 2147483647, 1489083519, 0, 234363721, 1290548373, 0]
Current values: 9412276676 [695300460, 2147483647, 1452183187, 2147483647, 0, 0, 0, 570277505, 252064583, 2147483647]
Current values: 9412276676 [941219147, 941226725, 941226725, 941238796, 941219147, 941247715, 941238795, 941234946, 941189734, 941234946]
Current values: 9412276676 [941306524, 941145153, 941241743, 940668167, 942314400, 941491117, 940668168, 941145153, 941306524, 940989727]
Current values: 9412276676 [945548859, 939149475, 935477311, 941294057, 944294715, 940031668, 940860151, 940662863, 940662862, 944294715]
Current values: 9412276676 [941254898, 941342907, 941188859, 941250824, 941250825, 940973864, 941078878, 941373381, 941373381, 941188859]
Current values: 9412276676 [941147294, 941232689, 941132597, 941330728, 941281708, 941236213, 941147294, 941265970, 941236214, 941265969]
......
</pre>
 
9,476

edits