传统锁如何防止 Java 中的并行访问?

How do conventional locks protect from parallel access in Java?

我们在 Java 中了解到的关于 并发的第一件事是我们使用 locks (synchronized keyword, Lock/ReadWriteLock interface) 以防止 并发 访问。例如:

synchronized void eat(){
        //some code
    }

理论上这个方法eat()可以单线程执行。尽管有很多线程等待执行它,但只有一个线程会占用 lock。但是接下来并行,让我三思而后行。

我有 4 个核心 CPU。这意味着我可以 并行 执行 4 个任务。是的,锁可以由单个线程获取。但是有没有可能发生 4 个线程调用方法 eat() 并在几乎同时使用 lock,尽管有一个 lock需要被收购才能真正做任何事情?

Java 会发生这样的事情吗?我想它不能,但我不得不问这个。而且我刚才说的一个case怎么处理的?

简答 - JVM 保留了一个试图获取锁的线程列表。

更多详情

https://wiki.openjdk.java.net/display/HotSpot/Synchronization

此外,值得一提的是,列表(又名“膨胀锁”)仅在真正需要时创建(== 发生锁争用时)。

...4 threads...take a lock at the LITERALLY same time...

这不可能发生。任何“同步”操作(例如,“获取锁”)都必须在系统的主内存上操作,而在任何传统计算机系统中,只有一条内存总线。多个 CPU 同时访问主内存在物理上是不可能的。

如果两个 CPU决定 几乎同时访问内存,硬件保证其中一个会“赢得”比赛并取得第一名, 而另一个则被迫等待。