多线程与异步

多线程与异步

多线程与异步不是一个概念
多线程是异步的一种实现方式
异步是最终目的
参考

一、定义:

  • 同步:线程(进程)在执行过程中,按从上到下的顺序依次执行代码
  • 异步:
    • 彼此独立,在等待某事件的过程中继续做自己的事,不需要等待这一事件完成后再工作。
    • 调用方法的主线程干一件事的时候,不需要同步等待另一个线程完成,此时主线程可以干其他事情。
    • 与任务相关
  • 多线程:
    • 程序设计逻辑层概念
    • 具体执行者相关
    • 进程中并行/并发运行的一段代码,可以实现线程间的切换执行。
    • 在单核处理器上,多线程往往会给人程序是在并行执行的错觉,本质:,处理器是通过调度算法在多线程之间进行切换和调度。或者根据外部输入(中断)和线程的优先级的组合来进行线程的切换。
    • 在多核处理器上,线程才是真正的并行运行。多个处理器同时执行多个线程,以达到更加高效的处理。
  • 异步模型:允许同一时间发生(处理)多个事件。程序调用一个耗时较长的功能(方法)时,它并不会阻塞程序的执行流程,程序会继续往下执行。当功能执行完毕时,程序能够获得执行完毕的消息或能够访问到执行的结果(如果有返回值或需要返回值时)
  • 异步编程设计:
    • 针对耗时性功能,提供方法/函数
    • 函数的参数中包含一个额外的参数,用于回调。
    • 这个函数往往称作回调函数。当比较耗时的功能执行完毕时,通过回调函数将结果返回。两个经典例子让你彻底理解java回调机制

      多线程与异步_第1张图片
      多线程与异步_第2张图片

二、举例:

情景:厨师、饭店订单、蒸鸡蛋和烤面包

  • 同步:这个厨师先蒸鸡蛋,蒸鸡蛋过程中不能烤面包、也不能干别的,只能等待;
  • 异步:单线程
    • 先蒸鸡蛋,鸡蛋在蒸的时候,去烤面包,面包在烤的过程中,鸡蛋熟了,不管是不是在给面包切片还是在等待面包烤熟,都要先去处理鸡蛋(如把鸡蛋从锅里端上来,送给客人),然后再回来处理烤面包,面包在烤的过程中可以打扫厨房,等烤面包好的时候,再去处理烤面包(如:送给客人)
  • 多线程::你雇多个厨师,一个蒸鸡蛋,另一个烤面包,你作为资源协调者,协调他们对物品的先后顺序,不让吵架(多线程的资源共享),同时你要给两个人money(多线程的性能损耗)

三、推荐:

限制分类:

  • IO限制:数据传输上的数据等待,本身消耗计算量不大,重要事情不是程序完成的。如console.readkey() 网络数据下载,
  • 计算限制:执行大量计算的操作

计算限制的任务:

  • 多请厨师(多开线程),最好和处理器数一致,每个任务分配一个线程,一个线程一个处理器(避免上下文切换),
  • 每个处理器去处理任务,这会加快任务的处理速度。

计算不限制的任务:

  • 不使用多线程,单线程的task
  • task的主要作用是不堵塞主线程,构建响应灵敏的程序,不一定会开辟多个线程。而多线程一定是开辟多个线程并发执行的。
  • Task中再遇到Await后,方法立即返回,不会因为await关键字而阻塞当前线程,当await关键字标记的语句执行完成后才会继续执行await后面的语句。
  • Task会中断方法的执行,但是不会阻塞线程,用其余的cpu片段处理别的任务。但是锁会阻塞方法所在的线程,造成活锁(基元用户模式构造造成)

推荐原则是:
客户端应用程序:用多线程方式处理计算限制的操作,用task处理IO限制的操作
服务器应用程序:始终用Task

你可能感兴趣的:(并发编程,java)