Java 科特林同步

Java 科特林同步,java,concurrency,kotlin,Java,Concurrency,Kotlin,过去几周我一直在学习java多线程。我学习了synchronized,并理解synchronized可以避免不同线程同时访问相同的属性。 我写这段代码是为了在同一个线程上运行两个线程 val gate = CyclicBarrier(3) val obj = SynchronizedCounter() var nah = object : Thread() { override fun run() { gate.await() obj.increment

过去几周我一直在学习java多线程。我学习了synchronized,并理解synchronized可以避免不同线程同时访问相同的属性。 我写这段代码是为了在同一个线程上运行两个线程

val gate = CyclicBarrier(3)
val obj = SynchronizedCounter()

var nah = object : Thread() {
    override fun run() {
        gate.await()
        obj.increment()
    }
}

var blah = object : Thread() {
    override fun run() {
        gate.await()
        println(obj.value())
    }
}

nah.start()
blah.start()

gate.await()

class SynchronizedCounter {
    private var c = 0

    @Synchronized
    fun increment() {
        c++
    }

    @Synchronized
    fun decrement() {
        c--
    }

    @Synchronized
    fun value(): Int {
        return c
    }
}
输出:0
不会返回1吗?因为第二个线程在第二个线程之后运行,所以
nah
blah
都将作业设置为在不同的线程上运行。因此,当它们每次调用
start
时,它们只是标记线程调度程序以启动它们
start
立即返回,当前线程继续运行代码的主线,直到发生某种事情使其延迟。在这一点上,调度器做它的事情,运行任何准备好并等待运行的东西。你不应该期待一个特定的订单,也不应该试图预测一个订单。这就是为什么要在代码中使用同步结构


您可以在单线程执行器上运行任务,如SO answer中所示(但对于java,您必须进行调整)。

这里没有理由要求特定的执行顺序。这里的规则是OS线程调度程序。它遵循自己的原则policies@OliverCharlesworth关于同步注释呢?在本例中,有两个线程访问同一个对象。您应该先了解发生了什么。如果将
wait
更改为第一个线程中的最后一条语句,则始终可以看到预期结果
1