JUC并发编程 01——多线程基础知识

一.线程应用

异步调用

以调用方角度来讲,如果

  • 需要等待结果返回,才能继续运行就是同步
  • 不需要等待结果返回,就能继续运行就是异步

应用

  • 比如在项目中,视频文件需要转换格式等操作比较费时,这时开一个新线程处理视频转换,避免阻塞主线程
  • tomcat 的异步 servlet 也是类似的目的,让用户线程处理耗时较长的操作,避免阻塞 tomcat 的工作线程
  • ......

并行调用

在项目开发中,经常会遇到一个问题:在一个后端接口里,往往会进行多项耗时任务(相互之间独立,没有依赖)的操作。

如:让你设计一个APP首页查询的接口,它需要查用户信息、需要查banner信息、需要查标签信息等等。一般情况,会实现如下:

public AppHeadInfoResponse queryAppHeadInfo(AppInfoReq req) {
    //查用户信息
    UserInfoParam userInfoParam = buildUserParam(req);
    UserInfoDTO userInfoDTO = userService.queryUserInfo(userInfoParam);
    //查banner信息
    BannerParam bannerParam = buildBannerParam(req);
    BannerDTO bannerDTO = bannerService.queryBannerInfo(bannerParam);
    //查标签信息
    LabelParam labelParam = buildLabelParam(req);
    LabelDTO labelDTO = labelService.queryLabelInfo(labelParam);
    //组装结果
    return buildResponse(userInfoDTO,bannerDTO,labelDTO);
}

以上的代码实现中,查询用户、banner、标签信息,是串行的。 如果查询用户信息耗时200ms,查询banner信息100ms,查询标签信息200ms的话,耗时就是500ms了。

JUC并发编程 01——多线程基础知识_第1张图片

我们可以对这些耗时任务进行并行操作,从而使得:响应时间 约等于 耗时最大的任务处理时间,这样可以大大降低系统的响应时间,如下图所示:

JUC并发编程 01——多线程基础知识_第2张图片

注意

  • 单核 cpu 下,多线程不能实际提高程序运行效率,只是为了能够在不同的任务之间切换,不同线程轮流使用cpu ,不至于一个线程总占用 cpu,别的线程没法干活
  • 多核 cpu 可以并行跑多个线程,但能否提高程序运行效率还是要分情况的
  • IO 操作只占用少量 cpu,只是我们一般拷贝文件使用的是【阻塞 IO】,这时相当于线程虽然只占用少量 cpu,但需要一直等待 IO 结束,没能充分利用线程。所以才有后面的【非阻塞 IO】和【异步 IO】优化

二.Java线程相关概念

进程

是程序的⼀次执⾏,是系统进⾏资源分配和调度的独⽴单位,每⼀个进程都有它⾃⼰的内存空间和系统资源

线程

线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。线程是系统调度的基本单位。

管程(Monitor,监视器)

  • 也就是我们平时所说的锁,Monitor其实是一种同步机制,他的义务是保证(同一时间)只有一个线程可以访问被保护的数据和代码。
  • JVM中同步是基于进入和退出监视器对象(Monitor,管程对象)来实现的,每个对象实例都会有一个Monitor对象,Monitor对象会和Java对象一同创建并销毁,它底层是由C++语言来实现的。

JUC并发编程 01——多线程基础知识_第3张图片

JVM第3版描述如下:

JUC并发编程 01——多线程基础知识_第4张图片

三.用户线程和守护线程

Java线程分为用户线程和守护线程,线程的daemon属性为true表示是守护线程,false表示是用户线程。

守护线程

是一种特殊的线程,在后台默默地完成一些系统性的服务,比如垃圾回收线程。当程序中所有用户线程执行完毕之后,不管守护线程是否结束,系统都会自动退出。

用户线程

是系统的工作线程,它会完成这个程序需要完成的业务操作。

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