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 ...");}}

推薦閱讀