对于后端开发来说,上下文我们常接触.
那什么是线程的上下文切换?
1.线程的上下文切换
在基础篇(一)中,我们讲到了时间片的概念.在单核处理器中,CPU就是通过给每个线程分配时间片执行来实现多线程.时间片是CPU分配给每个线程的执行时间段,这段时间都很短,只有几毫秒(ms),所以CPU必须来回切换各个线程来执行各自的任务,这样,对外看来,是在同时执行多个任务.
可能让我们疑惑的是,CPU如何保证下次再执行某个线程时,能正确记住该线程执行任务的状态?这就是我们要说的线程的上下文切换.CPU通过时间片分配算法来实现多任务,当前任务执行完对应的时间片后,需要切换到下一个任务.但是,在切换到下一个任务之前,需要保存上一个任务的状态,以便下次切换到该任务时,能正确的加载该任务的状态.这个过程就叫做线程的上下文切换.
举个例子,我记得上小学时候,老师讲课中间,其他老师会半途过来借东西,然后老师需要停下讲课内容,然后把东西借出去,然后说一句:我们继续.在这个过程中,老师必须要在脑子中记忆刚到的地方,不至于被其他事情打断后重来.这个过程就是上一件事情和下一件事情之间的切换.
因为有其他任务/事情插入,所以我们正在做的任务/事情会被中断,影响效率.因此,多线程任务的上下文切换是会影响执行效率的.
2.多线程执行与串行执行效率比较
多线程执行一定快吗?答案是不一定.我们模拟下面的执行过程.
public class CurrentSpeedTestDemo { private static final long count = 10000l; public static void main(String[] args) throws InterruptedException { concurrencyCount(); serialCount(); } private static void concurrencyCount() throws InterruptedException { long start = System.currentTimeMillis(); final Thread thread = new Thread(new Runnable() { @Override public void run() { int b = 0; for (long i = 0; i < count; i++) { b += 5; } System.out.println("并行执行得到:b=" + b); } }); thread.start(); long time = System.currentTimeMillis() - start; System.out.println("并行执行花费时间:" + time+"ms"); } private static void serialCount() { long start = System.currentTimeMillis(); int b = 0; for (long i = 0; i < count; i++) { b += 5; } long time = System.currentTimeMillis() - start; System.out.println("串行执行得到:b=" + b); System.out.println("串行执行花费时间:" + time+"ms"); } }
执行效果如下:(这是我的电脑执行效果)
从执行测试效果可以看出,当累加操作在1万次时,并行是慢于串行执行的.
3.减少上下文切换
减少上下文切换的方法有多种,常用的有 无锁并发编程,CAS,使用最少线程,使用协程.
①无锁并发编程:在编程中,首先考虑无锁实现.
②CAS:比较交换,在Java的原子类实现中,使用CAS来做数据更新.
③使用最少线程:在并发很小的情况下,尽量不使用大量线程.
④使用协程:协程可以实现在单线程的情况下多任务的切换.
相关推荐
- **避免过度使用同步**:合理利用非阻塞并发工具,减少线程上下文切换。 - **线程局部变量**:`ThreadLocal`用于存储每个线程的私有数据,避免数据冲突。 - **异常处理**:确保线程中的异常不会无声无息地消失,...
本篇文章将围绕Java多线程与并发编程的核心概念和技术进行深入探讨,帮助读者建立系统的知识体系,并掌握相关的实践方法。 #### 背景介绍 随着互联网应用规模的不断扩大,现代应用面临着高并发请求、CPU密集型操作...
- 并发:在单个处理器上,操作系统通过快速切换线程上下文,使得多个线程看起来像是在同时执行,但实际上是交替进行的。 2. 比较 - 并行强调的是真正意义上的同时执行,通常需要多核或多处理器支持。 - 并发则更...
本篇总结涵盖了Java多线程的基础概念、创建与启动、线程调度、同步与协作以及新特性。 **一、Java线程:概念与原理** 1. **线程与进程**: - **进程**:是操作系统资源分配的基本单位,每个进程都有独立的内存...
本篇将详细阐述Java多线程的基础知识,包括线程的概念、创建线程的方式以及相关注意事项。 1. **线程的基本概念** - **进程**:进程是操作系统资源分配的最小单位,它代表了一个正在执行的程序实例。当CPU从磁盘...
这篇总结将深入探讨Java多线程的基础概念、特性以及常见用法,旨在为初学者提供一个全面的学习指南。 一、线程的基本概念 在Java中,线程是程序执行的最小单位,每个线程都有自己的程序计数器、虚拟机栈、本地方法...
1. **多线程基础** - **线程与进程**:线程是操作系统分配CPU时间的基本单位,而进程则包含一个或多个线程,是资源分配的最小单位。在Cocos2d-x中,我们主要关注线程的管理。 2. **Cocos2d-x中的线程支持** - **...
一、C#多线程基础 1.1 线程概述:线程是操作系统分配CPU时间的基本单位,每个进程至少包含一个线程。多线程允许程序同时执行多个任务,提高了计算资源的利用率。 1.2 创建线程:在C#中,可以通过继承`System....
3. 调用`start()`方法启动线程,此时`run()`方法将在新的线程上下文中执行。 然而,线程本身并不提供超时控制功能。为了实现超时,我们需要结合使用`Future`接口和`ExecutorService`。`ExecutorService`是Java并...
Java线程机制是抢占式的,这意味着调度机制会周期性地中断线程,并将其上下文切换到另一个线程,这样每个线程都会被分配一个合理的执行时间来驱动其任务。这种机制使得线程之间的调度更加灵活。 **2. 线程同步** -...
线程性能优化也是多线程编程的重要一环,包括避免不必要的上下文切换、合理分配任务、减少锁的使用等。在处理大量并发时,线程池(ThreadPool)可以提高效率,避免频繁创建和销毁线程的开销。 最后,调试多线程程序...
这可能涉及到减少线程上下文切换、合理分配线程优先级、使用异步I/O等方法。 7. **编程语言与库**:实现多线程游戏可能需要用到特定的编程语言和库,如C++中的`std::thread`,Java的`Thread`类,或者Python的`...
本篇文章将详细讲解如何在 Delphi 中创建和使用多线程,以 `ThreadExample` 为例,展示一个简单的多线程应用。 1. **线程基础** - 线程是操作系统中的基本执行单元,每个线程都有自己的栈空间,共享同一进程的内存...
一、多线程基础 1.1 线程定义:线程是程序执行的最小单元,它共享进程的内存空间,拥有自己的执行栈和程序计数器。在一个进程中可以存在多个线程,它们相互协作完成复杂的任务。 1.2 多线程优点: - 提高资源利用...
这是因为过多的线程会导致上下文切换开销增加,反而降低效率。 ```java int threadCount = Runtime.getRuntime().availableProcessors() * 2; ``` 3. **如果任务间相互有依赖,如何处理?** - Java提供了`...
- **性能考量**:线程上下文切换和同步操作会影响性能,应尽可能减少不必要的同步和上下文切换。 3. **Java并发框架**: - **JVM线程**:JVM启动后创建主线程执行Main方法,还有垃圾回收、终结处理等辅助线程。 ...
过多的线程可能会消耗大量内存,导致上下文切换开销增大,反而降低程序效率。合理地平衡线程数量与系统负载至关重要。同时,使用异步编程模型(如`async/await`)可以在不创建额外线程的情况下实现并发,这也是C#...
线程是操作系统分配CPU时间的基本单元,一个进程中可以包含多个线程,它们共享同一块内存空间,可以并发执行,减少了上下文切换的时间开销。在Qt中,多线程主要通过`QThread`类来实现。 1. **QThread**:Qt中的`...
Java并发编程是Java语言中的一个高级特性,它允许程序在多线程环境中运行,从而有效地利用多核处理器的能力,提高程序的执行效率。并发编程涉及到线程管理、同步机制、共享资源访问控制等多个方面,是现代软件开发中...