Java单核CPU下线程切换访问同步方法的执行场景求证
Java同步方法在单核CPU下的执行场景疑问
我定义了如下同步方法:
public synchronized void doSomething() { // do something }
假设有两个或多个线程,运行环境为单核CPU,线程会由CPU调度切换执行。因为该方法是同步方法,同一时刻仅能有一个线程执行它,其余线程会被阻塞。
我设想了两种执行场景:
- 场景1:线程1在执行doSomething方法的过程中,CPU将执行权切换给线程2,线程2发现该方法已被线程1锁定,无法执行;随后CPU切回线程1,使其继续执行doSomething方法,甚至可能线程1会再次执行该方法。
- 场景2:线程1执行doSomething方法期间,线程2全程处于阻塞状态;线程1执行完该方法后,CPU才将执行权切换给线程2,此时线程2可开始执行doSomething方法。
想请教哪种场景是正确的?
正确场景解析
场景1是符合实际执行逻辑的。
在单核CPU环境下,线程的切换由操作系统调度器决定,锁机制不会阻止调度器切换CPU执行权。当线程1正在执行同步方法doSomething时,若调度器将CPU时间片分配给线程2,线程2尝试进入该方法时会发现锁已被线程1持有,此时线程2会进入阻塞状态(等待锁释放),调度器会再次将CPU执行权切换给线程1,让它继续执行doSomething直到完成并释放锁。
之后,当调度器再次切换到线程2时,线程2才能获取锁并开始执行doSomething。甚至如果调度器再次把时间片分给线程1,线程1还可以再次获取锁执行该方法(只要锁已释放或它仍持有锁)。
场景2的错误在于,它误以为线程持有锁期间CPU不会切换到其他线程,但实际上操作系统的线程调度和Java锁机制是独立的,锁只控制方法的执行权限,不影响CPU的调度切换。
内容的提问来源于stack exchange,提问作者elvis
相关产品推荐
相关产品推荐

