传统锁如何防止 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决定 几乎同时访问内存,硬件保证其中一个会“赢得”比赛并取得第一名, 而另一个则被迫等待。
我们在 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决定 几乎同时访问内存,硬件保证其中一个会“赢得”比赛并取得第一名, 而另一个则被迫等待。