JUC学习笔记——进程与线程

JUC学习笔记——进程与线程在本系列内容中我们会对JUC做一个系统的学习 , 本片将会介绍JUC的进程与线程部分
我们会分为以下几部分进行介绍:

  • 进程与线程
  • 并发与并行
  • 同步与异步
  • 线程详解
进程与线程在这一小节我们将简单介绍进程与线程
进程首先我们来简单了解一下程序:
  • 程序由指令和数据组成 , 我们必须将指令加载至 CPU,数据加载至内存 。在指令运行过程中还需要用到磁盘、网络等设备 。
接下来我们才能讲解进程的定义:
  • 进程就是用来加载指令、管理内存、管理 IO 的
  • 当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程 。
  • 进程就可以视为程序的一个实例 。大部分程序可以同时运行多个实例进程,也有的程序只能启动一个实例进程 。
线程我们来简单介绍一下线程:
  • 一个进程之内可以分为一到多个线程 。
  • 一个线程就是一个指令流,将指令流中的一条条指令以一定的顺序交给 CPU 执行
  • Java 中 , 线程作为最小调度单位,进程作为资源分配的最小单位 。在 windows 中进程是不活动的,只是作为线程的容器
两者区别我们来介绍一下进程与线程之间的区别:
  • 进程基本上相互独立的,而线程存在于进程内,是进程的一个子集
  • 进程拥有共享的资源,如内存空间等,供其内部的线程共享
  • 线程更轻量,线程上下文切换成本一般上要比进程上下文切换低
此外两者的通信方式也不相同:
  • 进程通信:同一台计算机的进程通信称为 IPC;不同计算机之间的进程通信,需要通过网络,并遵守共同的协议 , 例如 HTTP
  • 线程通信:线程通信相对简单,因为它们共享进程内的内存,一个例子是多个线程可以访问同一个共享变量
并发与并行在这一小节我们将简单介绍并发与并行
并发首先我们需要了解一下任务调度器:
  • 单核 cpu 下,线程实际还是 串行执行 的 。
  • 操作系统中有一个组件叫做任务调度器,将 cpu 的时间片分给不同的程序使用 。
那么我们的并发实际上就是根据任务调度器来工作的:
  • 并发是借助任务调度器 , 在一段时间段内将CPU分给多个线程使用,但由于切换快时间短,所以被看作是同时进行
  • 一般会将这种 线程轮流使用 CPU 的做法称为并发
  • 实际上并发的情况是:微观串行,宏观并行
通俗来讲:
  • 并发(concurrent)是同一时间应对(dealing with)多件事情的能力
例如下图:
CPU时间片 1时间片 2时间片 3时间片 4core线程 1线程 2线程 3线程 4并行并行的概念就相对而言比较简单了:
  • 并行就是借助多核CPU , 确确实实地在同一时间执行多个进程
通俗来讲:
  • 并行(parallel)是同一时间动手做(doing)多件事情的能力
例如下图:
CPU时间片 1时间片 2时间片 3时间片 4core 1线程 1线程 1线程 3线程 3core 2线程 2线程 4线程 2线程 4同步与异步在这一小节我们将简单介绍并发与并行
同步与异步概念首先我们来简单介绍一下同步与异步:
  • 需要等待结果返回才能继续执行的操作就是同步操作
  • 不需要等待结果返回就可以继续执行的操作就是异步操作
另外同步操作还有另一个概念:
  • 在多线程中,表示多线程的步调一致
同步与异步选择方法我们的同步与异步的选择通常会决定程序的运行速度,因而选择同步或异步是非常重要的
我们先来介绍同步与异步的实现方式:
  • 同步就是在一个线程内完全执行所有命令
  • 异步可以在多线程中实现 , 当一个线程执行复杂操作比较耗时时,另一个线程可以执行其他简单操作
我们再来介绍同步与异步的选择方法:
  • 针对比较繁琐的操作,我们通常会单独创建一个新线程来进行处理,避免阻塞主线程
  • Tomcat里面的异步Servlet也是异步操作 , 让用户线程处理耗时较长的操作,避免阻塞Tomcat的工作线程
  • UI程序中,开线程进行其他操作,避免UI线程
我们分别给出同步异步的代码展示:
// 同步代码package cn.itcast.n2;import cn.itcast.Constants;import cn.itcast.n2.util.FileReader;import lombok.extern.slf4j.Slf4j;@Slf4j(topic = "c.Sync")public class Sync {public static void main(String[] args) {FileReader.read(Constants.MP4_FULL_PATH);log.debug("do other things ...");}}// 异步代码package cn.itcast.n2;import cn.itcast.Constants;import cn.itcast.n2.util.FileReader;import lombok.extern.slf4j.Slf4j;@Slf4j(topic = "c.Async")public class Async {public static void main(String[] args) {new Thread(() -> FileReader.read(Constants.MP4_FULL_PATH)).start();log.debug("do other things ...");}}

推荐阅读