Java中CPU如何将执行从一个线程切换到另一个线程来访问锁资源?

问题描述 投票:0回答:1

我正在学习 Java 中的多线程,我有一个简短的问题。 我有一个同步块或方法和 2 个(或更多)线程。而且我只有一个 CPU,只有一个核心,因此当 CPU 决定从一个线程切换到另一个线程时,2 个线程将按顺序工作。

public synchronized void doSomething() {
    // do something
}

因此,一次只有一个线程会执行此方法,因为它是同步的。另一个线程被阻塞,无法执行该方法,直到第一个线程完成执行。

我认为有两种情况,CPU可以在thread1完成doSomething()执行之前将执行从thread1切换到thread2。如果CPU这样做,则意味着线程1将停止执行doSomething()并让它未完成,线程2将看到doSomething()被锁定,因为线程1执行了它。之后我认为CPU会切换回thread1并继续执行doSomething()。在 CPU 切换回线程 2 之前,线程 1 可能会再次开始执行 doSomething() 。

第二种情况,线程1执行doSomething(),线程2在线程1执行该方法的整个期间被阻塞。当线程 1 完成 doSomething() 的执行后,CPU 将切换到线程 2,该线程将开始执行 doSOthing(),因为此时该方法尚未锁定。

有人可以解释一下什么是正确的情况吗?

java multithreading locking cpu synchronized
1个回答
0
投票

您缺少图片的一部分。这就是人们所说的“调度器”。它是操作系统的组件,负责决定运行哪些线程、何时运行以及运行多长时间。

Java中CPU如何将执行从一个线程切换到另一个线程来访问锁资源?

事实并非如此。这不是 CPU 的工作。 CPU 仅执行简单的指令,一个接一个,直到被某些外部硬件事件中断。然后,它不是切换到另一个线程,而是切换到操作系统中的中断处理程序例程

外部中断源之一是(心跳)计时器,它会定期中断 - 每秒数十次到数千次,具体取决于操作系统。每次心跳/计时器滴答时,中断处理程序都会调用调度程序,调度程序会决定从中断返回后下一个要运行的程序线程。

调度程序有一组所谓的“队列”,它们可能是也可能不是实际的先进先出队列,系统中的每个活动线程都属于一个队列。最重要的队列是运行队列,它包含所有“准备运行”的线程。如果某个线程在运行队列中,则意味着它实际上没有运行的唯一原因是,它正在等待调度程序将其放到 CPU 上。

在操作系统从定时器中断返回之前,调度程序从运行队列中选择一个线程作为下一个运行的线程。队列永远不会为空,因为即使没有应用程序线程准备运行,系统的空闲线程也始终准备就绪。

一次只有一个线程会执行此方法,因为它是同步的。另一个线程被阻塞,无法执行该方法,直到第一个线程完成执行。

程序的线程必须进行系统调用来锁定对象,然后才能进入同步块,如果您的线程 B 在对象已锁定时尝试它,操作系统会将其移动到“等待队列”,即与该对象相关联。该线程将不再可运行。如果在线程 A 实际运行时心跳随后出现,那么调度程序甚至不会尝试重新启动线程 B,因为线程 B 不在运行队列中。如果线程 A 是唯一可运行线程(没有其他正在运行的程序),那么心跳中断将返回到线程 A。

当线程 A 解锁对象时,这是另一个系统调用。并且,当任何对象被解锁时,调度程序都会将至少一个线程(可能是所有线程,这取决于调度程序的策略)从相应的等待队列移动到运行队列。不过,您的线程 B 现在可以再次运行,系统调用是立即返回到线程 B 还是再次返回到线程 A 取决于(再次)调度程序策略。

© www.soinside.com 2019 - 2024. All rights reserved.