| import java.util.concurrent.atomic.AtomicInteger |
| import java.util.concurrent.atomic.AtomicReference |
| import java.util.concurrent.CyclicBarrier |
| import kotlin.concurrent.thread |
| import kotlin.reflect.jvm.* |
| |
| const val N_THREADS = 50 |
| |
| class Delegate { |
| operator fun getValue(x: Any?, y: Any?): String = "OK" |
| operator fun setValue(x: Any?, y: Any?, z: String) {} |
| } |
| |
| var property by Delegate() |
| |
| fun main() { |
| val reference = ::property |
| |
| val gate = CyclicBarrier(N_THREADS + 1) |
| var fail = AtomicReference<Throwable?>(null) |
| var finished = AtomicInteger(0) |
| for (i in 0 until N_THREADS) { |
| thread { |
| gate.await() |
| reference.isAccessible = true |
| try { |
| reference.getDelegate()!! |
| } catch (e: Throwable) { |
| fail.set(e) |
| } |
| finished.incrementAndGet() |
| } |
| } |
| |
| gate.await() |
| |
| while (finished.get() != N_THREADS) Thread.sleep(25L) |
| fail.get()?.let { throw it } |
| } |