JAVA多线程(一)基本概念和上下文切换性能损耗

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

JAVA多线程(一)基本概念和上下文切换性能损耗

1 多线程概念

在理解多线程之前,我们先搞清楚什么是线程。根据维基百科的描述,线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是行程中的实际运行单位。一条线程指的是进程中一个单一顺序的控制流,一個进程中可以并行多个线程,每条线程并行执行不同的任务。每个线程共享堆空间,拥有自己独立的栈空间。

这里反复出现的概念是线程和进程,我们在这里列出它们的区别:

线程划分尺度小于进程,线程隶属于某个进程;

进程是CPU、内存等资源占用的基本单位,线程是不能独立占有这些资源的;

进程之间相互独立,通信比较困难,而线程之间共享一块内存区域,通信方便;

进程在执行过程中,包含比较固定的入口、执行顺序和出口,而进程的这些过程会被应用程序控制。

多线程是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时

间执行多个线程,进而提升整体处理效能。

2 为什么要使用多线程

随着计算机硬件的发展,多核CPU已经屡见不鲜了,甚至手机处理器都早已是多核的天下。这就给我们使用多线程提供了硬件基础,但是,只是因为硬件让我们可以实现多线程,就要这样做吗?一起来看看多线程的优点:

更高的运行效率。在多核CPU上,线程之间是互相独立的,不用互相等待,也就是所谓的“并行“。举个例子,一个使用多线程的文件系统可以实现高吞吐量和低延迟。这是因为我们可以用一个线程来检索存储在高速介质(例如高速缓冲存储器)中的数据,另一个线程检索低速介质(例如外部存储)中的数据,二者互不干扰,也不用等到另一个线程结束才执行;

多线程是模块化的编程模型。在单线程中,如果主执行线程在一个耗时较长的任务上卡住,或者因为网络响应问题陷入长时间等待,此时程序不会响应鼠标和键盘等操作。多线程通过将程序分成几个功能相对独立的模块,单独分配一个线程去执行这个长耗时任务,不影响其它线程的执行,就可以避免这个问题;

与进程相比,线程的创建和切换开销更小。使用多线程为多个客户端服务,比使用多进程消耗的资源少得多。由于启动

一个新的线程必须给这个线程分配独立的地址空间,建立许多数据结构来维护线程代码段、数据段等信息,而运行于同一进程内的线程共享代码段、数据段,线程的启动和切换开销小得多。一个典型的应用例子就是Apache HTTP服务器所使用的线程池:一个监听线程池专门用来监听是否有请求进入,另一个服务器线程池用来处理这些请求;

通信方便。因为线程共享栈空间,可以通过线程之间共享的数据、代码和文件来进行线程之间的通信(详见我的另一篇JAVA多线程(四)数据共享)。相比之下,进程之间的通信则需要专门的消息传递机制;

使用多线程能简化程序的结构,使程序便于理解和维护。一个复杂的进程可以分成多个线程来执行;

更高的资源利用率。多CPU或多核计算机本来就具有执行多线程的能力,如果只使用单个线程,将无法重复利用计算机资源,造成巨大浪费。

3 多线程上下文切换的性能损耗

前面夸了多线程的优点,凡事都有两面性,使用多线程也有弊端。尽管使用多线程往往可以获得更大的吞吐率和更短的响应时间,但是,多线程程序不一定比单线程程序执行速度快。很多线程存在情况下,线程之间的切换会非常频繁,切换带来的性能损耗是非常可观的。

3.1 上下文切换的概念

先来解释一下什么是上下文切换(context switch)。在多任务处理系统中,作业数通常大于CPU数。为了让用户觉得这些任务在同时进行,CPU给每个任务分配一定时间,把当前任务状态保存下来,当前运行任务转为就绪(或者挂起、删除)状态,另一个被选定的就绪任务成为当前任务。之后CPU可以回过头再处理之前被挂起任务。上下文切换就是这样一个过程,它允许CPU记录并恢复各种正在运行程序的状态,使它能够完成切换操作。在这个过程中,CPU会停止处理当前运行的程序,并保存当前程序运行的具体位置以便之后继续运行。

上下文切换在不同的场合有不同的含义,在下表中列出:上下文切换种类

描述线程切换

同一进程中的两个线程之间的切换

进程切换

两个进程之间的切换

模式切换

在给定线程中,用户模式和内核模式的切换

地址空间切换

将虚拟内存切换到物理内存

相关文档
最新文档