根据我一直在阅读的定义:
线程基本上是并发运行的代码片段(at 同时)。
但是,它们如何与线程调度程序的存在同时运行?
我读到线程调度程序基本上随机选择一个线程在某个时刻从Runnable
线程池中运行。从那时起,我在一个精确的时间点得到了它,只有一个可运行的线程真正处于运行状态(运行)。 (所有这些都来自SCJP Sun认证程序员学习指南)任何人都可以澄清这个吗?
这些线程是否真正同时运行?
答案 0 :(得分:2)
但是,它们如何与线程调度程序的存在同时运行?
它们并不总是并发运行,调度程序的工作是交换正在运行的线程,以便它们看起来并发运行。也就是说你看得太快了。
调度程序使用0.1 ms的时间片。你只能看到10 - 25毫秒的闪烁,所以这对你来说太快了,但它很快就会交换线程,所以看起来有并发性。
e.g。你看不到电影从一帧跳到下一帧。每个帧每1/42秒更换一次,因此您认为在实际看到高速摄像机时会看到移动,屏幕看起来会有些跳动。
如果您有一个逻辑CPU,则所有线程都被交换到一个CPU。如果您有多个逻辑CPU,则可以立即运行一个小集,其余的必须等待。
答案 1 :(得分:0)
实际上它们是同时运行的,但从技术上讲它们不是(在单核CPU的情况下)。调度程序选择要运行的线程,为该线程执行一些指令,然后上下文切换以执行另一个线程的指令。所有这些都发生得如此之快,以至于线程似乎同时运行。使用多核心线程时,同样的概念适用,但它可以同时执行两个或多个线程。
虽然这在技术上是正确的,但在编程中假装你不知道这一点很有用。将Java中的线程视为实际并发运行。 java并发构造是一种抽象,因此您可以有效地并行运行命令,而无需知道操作系统级别及以下的内容。
答案 2 :(得分:0)
在多核处理器上是的,在单核上没有。 这是因为在多核处理器上实际上存在多个核来执行不同的逻辑,而不管其他核上发生了什么。这在单核处理器上是不可能的。为了在单个核心处理器上给出多线程的错觉,JVM在不同线程的执行之间随机且非常频繁地切换,以使其看起来好像很多事情同时发生。实际上,一次只发生一件事,但CPU只是对任务进行少量进展,然后切换到另一个任务并经常重复此过程。举个例子可以说我有这样的东西:
线程1
1-2-3-4-5
线程2
A-B-C-d-E
JVM会在执行两个线程之间切换,可能会给出类似这样的内容:
1-A-B-2-3-C-4-d-E-5
两个线程在同一时间(或大约)结束时,如果它们同时发生但实际上并不是这样。 请注意,我只是编写了这个订单,因为它是随机的,可能在不同的JVM或不同的机器上有所不同,但我希望你能看到我的意思。通常,JVM足以让它看起来像多线程,因为它不会对程序员产生影响。
答案 3 :(得分:0)
请参阅,许多线程可能会等待与I / O设备的某种交互。在这种情况下,调度程序停止执行该线程,从等待线程队列中选择一个线程并开始执行该线程。已停止的线程可以再次返回 ready 状态(它将再次置于等待队列中),然后它就可以进行调度/执行。
答案 4 :(得分:0)
考虑到这个问题和相关答案似乎可能通过不正确地使用术语而增加了对该主题的混淆,我将在讨论中添加。
这些线程是否真正同时运行?
是。无论机器是否具有多个核心,都是如此。根据机器具有多少核心,并发意味着什么改变。具体而言,具有多个核的机器能够并行执行。因此,没有并行性就可以实现并发性。
因为在存在多核计算机之前,计算机出现以同时运行多个线程 ,即使情况并非如此。这是通过各种类型的线程调度算法实现的,但最终结果是线程在 time 的一段时间内共享处理器。许多线程在时间跨度上进展。它们同时运行,因为通常情况是线程不能在一个时间量内完成。基于完全公平的循环调度程序的可视化将类似于:
T1-T2-T3-...-TN-T1-T2-T3...TN-...
-------------Time------------->
当存在多个内核,多个处理器或甚至线程(a.k.a HyperThreaded)处理器时,该机器能够并行执行线程。这意味着线程确实同时运行 。基于系统的简化可视化,看起来不再像您建议的那样需要线程调度程序,如下所示:
T1-T1-T1-T1-T1...
-----Time----->
T2-T2-T2-T2-T2...
但是 ,这里应该有一个明显的问题,即使存在多个核心,也必须使用线程调度程序修复。您能猜出即使在主要用于在互联网上玩游戏的计算机上,有多少线程同时运行?地段!目前还没有技术可用于为系统中的每个线程提供逻辑或其他专用内核。所以,我们今天所拥有的是并发并行。基于完全公平的循环调度程序的简化示例如下所示:
T1-T2-T3-...-TN-T1-T2-T3...TN-...
-------------Time------------->
T4-T5-T6-...-TM-T4-T5-T6...TM-...
您无法避免线程或进程调度程序,而不仅仅是因为运行的线程数量因为线程具有不同的优先级而必须抢占其他不太重要的线程以便为用户提供最佳体验。例如,线程处理键盘输入不能只是被抛入队列中,只要轮到它就可以运行。这样做会导致我的机器被粉碎成一百万件试图写这篇文章。
为了进一步阅读,我建议选择应对许多并发/多编程主题的假设go-to OS book。