百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

「知识科普」比多线程还快?了解下什么是协程

lipiwang 2024-11-01 14:10 9 浏览 0 评论

什么是线程

线程是操作系统能够进行运算调度的最小单位。大部分情况下,它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

在一些系统中,线程也被称之为轻量进程。而轻量进程一般指的内核线程。

一个进程可以有很多线程来处理,每条线程并行执行不同的任务。如果进程要完成的任务很多,这样需很多线程,也要调用很多核心。因此在多核的CPU上面使用多线程程序设计能更有效地利用CPU。

多线程示例:

@Test
    public void testThread() {
        Thread thread1 = new Thread(() -> funA(),"Thread-1");
        Thread thread2 = new Thread(() -> funB(),"Thread-2");
        Thread thread3 = new Thread(() -> funC(),"Thread-3");

        thread1.start();
        thread2.start();
        thread3.start();
    }

    public void funA() {
        System.out.println("A1");
        System.out.println("A2");
        System.out.println("A3");
    }

    public void funB() {
        System.out.println("B1");
        System.out.println("B2");
        System.out.println("B3");
    }

    public void funC() {
        System.out.println("C1");
        System.out.println("C2");
        System.out.println("C3");
    }

运行结果:

A1
C1
C2
C3
B1
A2
A3
B2
B3

线程调度示意图:

如上图,一个线程绑定一个任务,任务会在CPU内执行,在Windows和Liunx等系统中,任务的调度采用的时间片强占调用方式。任务的状态分为运行状态和就绪状。举个例子,当任务1进行到就绪状态时,就会进行中断处理,并保存当前任务相关的执行信息(存在内存中),操作系统内核会分配接下来可以执行哪个任务,我们假设分配给了任务3执行。当任务3中断了,可能跳到了任务2,也可能跳回到了任务1,读取保存的执行信息,继续执行起来。

这里就会有3个线程之间的来回切换。

线程阻塞切换需要在操作系统的内核上面切换,会有用户态到内核态的切换。

协程与线程

上面描述我们知道,线程中任务的调度是由内核操作的,会有用户空间到内核空间的跨越,不利于系统性能。而聪明的程序员想到,何不自己写一套程序来控制任务之间的调度呢,这样将任务调度控制在用户空间。

关于协程,我们来看看维基百科上面关于协程的介绍:

协程非常类似于线程。但是协程是协作式多任务的,而线程典型是抢占式多任务的。这意味着协程提供并发性而非并行性。协程相比线程,优势是它们可以用于硬性实时的语境(在协程之间的切换不需要涉及任何系统调用或任何阻塞调用),这里不需要用来守卫关键区块的同步性原语(primitive)比如互斥锁、信号量等,并且不需要来自操作系统的支持。有可能以一种对调用代码透明的方式,使用抢占式调度的线程实现协程,但是会失去某些利益(特别是对硬性实时操作的适合性和相对廉价的相互之间切换)。

线程是协作式多任务的轻量级线程,本质上描述了同协程一样的概念。其区别,如果一定要说有的话,是协程是语言层级的构造,可看作一种形式的控制流,而线程是系统层级的构造,可看作恰巧没有并行运行的线程。这两个概念谁有优先权是争议性的:线程可看作为协程的一种实现,也可看作实现协程的基底。

一个线程其实就是执行一个子程序,那么什么什么是子程序呢?

子程序就是函数,在Java中就是方法。如果一个funA调用了funB,funB调用funC,那么,需要先执行完funC,再执行funB,最后再执行funA。

整个子程序内部调用是通过栈来实现的。

那么协程跟子程序有什么关系呢?

其实协程也是一个子程序,但是在执行子程序的过程中,子程序的内部可以中断,转而去执行别的子程序,之后又可以回来执行当前的子程序。

这个是不是有点像CPU的中断。

我们来看一段代码:

funA() {
  println("A1");
  println("A2");
  println("A3");
}

funB() {
  println("B1");
  println("B2");
  println("B3");
}

funC() {
  println("C1");
  println("C2");
  println("C3");
}

如果上面的代码由协程执行,可能在执行funA的时候在内部某一点中断,然后就去执行funB,也有可能回去执行funC,最后的结果可能就是:

A1
A2
C1
C3
A3
B3
B2
C2
B1

在这里要注意的是3个函数之间是没有互相调用的。这里的显示也并没有使用多线程技术,而只是用了一个线程执行的。

既然多线程也能实现上面的功能,为什么还要诞生协程呢?

在协程中,子程序的切换不是线程间的切换,而是由程序本身去控制。所以相对于多线程,没有了线程之间来回切换的开销。特别是在线程数量很多的情况下。

如果在多线程中我们需要要操作共享资源,我们就需要使用锁,我们可能会使用各种不同级别的锁,甚至会使用操作系统层面的锁。如果是在协程中,就不需要使用锁了。

总的来说,协程提高了程序的执行的效率。如果我们的系统是多核的,我们可以利用多核加上协程最大程度地发挥系统性能。

有关协程的发展史

协程的概念最早在20世纪90年代就诞生了,而线程的概念是在80年代才提出的,就使用情况来说,协程的使用远远不如线程广泛。

近些年,一些编程语言的新贵Go和Kotlin纷纷引入了协程这个语言特性,使得协程这个似乎十分陌生的概念开始频繁进入大家的视野。

相信对于从事Java开发的程序员来说,没有听过协程也很正常,我也是在网上看到一篇腾讯的面试攻略,才知道有协程这个东西。

如果你掌握的语言是Go,Kotlin或者Python等语言,那就该了解下协程。大厂比较喜欢面试这些东西。

好了,如果别人问你什么是协程,你可以说:协程是一种轻量级线程。

参考

1.协程 - 维基百科,自由的百科全书 (wikipedia.org)-https://zh.wikipedia.org/wiki/协程

2.多线程 - 维基百科,自由的百科全书 (wikipedia.org)-https://zh.wikipedia.org/wiki/多线程

3.协程 - 廖雪峰的官方网站 (liaoxuefeng.com)-https://www.liaoxuefeng.com/wiki/897692888725344/923057403198272

相关推荐

ubuntu单机安装open-falcon极度详细操作

备注:以下操作均由本人实际操作并得到验证,喜欢的同学可尝试操作安装。步骤一1.1环境准备(使用系统:ubuntu18.04)1.1.1安装redisubuntu下安装(参考借鉴:https://...

Linux搭建promtail、loki、grafana轻量日志监控系统

一:简介日志监控告警系统,较为主流的是ELK(Elasticsearch、Logstash和Kibana核心套件构成),虽然优点是功能丰富,允许复杂的操作。但是,这些方案往往规模复杂,资源占用高,...

一文搞懂,WAF阻止恶意攻击的8种方法

WAF(Web应用程序防火墙)是应用程序和互联网流量之间的第一道防线,它监视和过滤Internet流量以阻止不良流量和恶意请求,WAF是确保Web服务的可用性和完整性的重要安全解决方案。它...

14配置appvolume(ios14.6配置文件)

使用AppVolumes应用程序功能,您可以管理应用程序的整个生命周期,包括打包、更新和停用应用程序。您还可以自定义应用程序分配,以向最终用户提供应用程序的特定版本14.1安装appvolume...

目前流行的缺陷管理工具(缺陷管理方式存在的优缺点)

摘自:https://blog.csdn.net/jasonteststudy/article/details/7090127?utm_medium=distribute.pc_relevant.no...

开源数字货币交易所开发学习笔记(2)——SpringCloud

前言码云(Gitee)上开源数字货币交易所源码CoinExchange的整体架构用了SpringCloud,对于经验丰富的Java程序员来说,可能很简单,但是对于我这种入门级程序员,还是有学习的必要的...

开发JAX-RPC Web Services for WebSphere(下)

在开发JAX-RPCWebServicesforWebSphere(上)一文中,小编为大家介绍了如何创建一个Web服务项目、如何创建一个服务类和Web服务,以及部署项目等内容。接下来小编将为大...

CXF学习笔记1(cxf client)

webservice是发布服务的简单并实用的一种技术了,个人学习了CXF这个框架,也比较简单,发布了一些笔记,希望对笔友收藏并有些作用哦1.什么是webServicewebService让一个程序可...

分布式RPC最全详解(图文全面总结)

分布式通信RPC是非常重要的分布式系统组件,大厂经常考察的Dubbo等RPC框架,下面我就全面来详解分布式通信RPC@mikechen本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》...

Oracle WebLogic远程命令执行0day漏洞(CVE-2019-2725补丁绕过)预警

概述近日,奇安信天眼与安服团队通过数据监控发现,野外出现OracleWebLogic远程命令执行漏洞最新利用代码,此攻击利用绕过了厂商今年4月底所发布的最新安全补丁(CVE-2019-2725)。由...

Spring IoC Container 原理解析(spring中ioc三种实现原理)

IoC、DI基础概念关于IoC和DI大家都不陌生,我们直接上martinfowler的原文,里面已经有DI的例子和spring的使用示例《InversionofControlContainer...

Arthas线上服务器问题排查(arthas部署)

1Arthas(阿尔萨斯)能为你做什么?这个类从哪个jar包加载的?为什么会报各种类相关的Exception?我改的代码为什么没有执行到?难道是我没commit?分支搞错了?遇到问题无法在...

工具篇之IDEA功能插件HTTP_CLENT(idea2021插件)

工具描述:Java开发人员通用的开发者工具IDEA集成了HTTPClient功能,之后可以无需单独安装使用PostMan用来模拟http请求。创建方式:1)简易模式Tools->HTTPCl...

RPC、Web Service等几种远程监控通信方式对比

几种远程监控通信方式的介绍一.RPCRPC使用C/S方式,采用http协议,发送请求到服务器,等待服务器返回结果。这个请求包括一个参数集和一个文本集,通常形成“classname.meth...

《github精选系列》——SpringBoot 全家桶

1简单总结1SpringBoot全家桶简介2项目简介3子项目列表4环境5运行6后续计划7问题反馈gitee地址:https://gitee.com/yidao620/springbo...

取消回复欢迎 发表评论: