Java進程與線程介紹及如何實現(xiàn)
1.前言
哈嘍大家好吖,今天來給大家分享這一段時間剛上手的Java多線程的學習,多線程在以后實際項目開發(fā)中是一個十分核心的內容,需要認真學習并加以掌握,剛上手概念比較多,希望大家沉下心來慢慢學習,那么讓我們開始這一部分的學習吧。
2.正文
在介紹線程之前,需要先講解以下進程相關的概念,進程與線程之間息息相關,并且以后面試的時候會對這部分的原理內容進行考察。
2.1什么是進程
進程(Process) 是計算機中執(zhí)行的程序的實例。它是操作系統(tǒng)分配資源和調度的基本單位。進程不僅包含程序代碼本身,還包括程序執(zhí)行時所需的資源和環(huán)境。每個進程都有獨立的內存空間、寄存器、堆棧、程序計數(shù)器等,它們使進程能夠在多任務操作系統(tǒng)中并發(fā)執(zhí)行而不互相干擾。
如何在電腦上查看進程呢,其實很簡單,打開任務管理器:

可以看到這里就標記著進程,當我們點到任務管理器詳細信息一欄時,每一個進程的相關信息都會展示出來,這里先大概感知一下進程到底是什么。
2.2PCB(進程控制塊)
操作系統(tǒng)通過管理進程來實現(xiàn)多任務操作,每個進程在操作系統(tǒng)中都有一個對應的進程控制塊(PCB),用于存儲進程的狀態(tài)、程序計數(shù)器、寄存器等信息。當發(fā)生上下文切換時,操作系統(tǒng)會保存當前進程的狀態(tài),加載另一個進程的狀態(tài),從而實現(xiàn)進程間的切換。
下面是PCB的相關屬性:
2.2.1進程id
PCB中的進程ID(Process ID,PID) 是操作系統(tǒng)用來唯一標識進程的一個標識符。每個進程在操作系統(tǒng)中都有一個獨一無二的PID,它用于區(qū)分不同的進程并在進程管理中進行調度、監(jiān)控和資源分配。

特點:
- 唯一性
- 每個進程都有一個唯一的PID,操作系統(tǒng)保證同一時刻不會有兩個進程擁有相同的PID。
- 生命周期
- 當一個進程創(chuàng)建時,操作系統(tǒng)為其分配一個PID;當進程終止時,PID被釋放,操作系統(tǒng)可以將其分配給新的進程。
2.2.2內存指針
內存指針(Memory Pointer)是一個重要的字段,用于保存與進程相關的內存管理信息。這個指針幫助操作系統(tǒng)追蹤進程使用的內存區(qū)域,包括代碼、數(shù)據、堆棧等。
內存指針都指向什么,都有什么作用呢:
- 如果這個指針存儲進程執(zhí)行的代碼,那么會使CPU能夠正確地加載和執(zhí)行指令。
- 如果這個指針指向數(shù)據段,那么會使操作系統(tǒng)在運行時管理數(shù)據的訪問。
2.2.3文件描述符表
文件描述符表是一個非常重要的字段,它用來管理進程與操作系統(tǒng)中文件的關系。文件描述符表存儲著進程打開的文件的相關信息,每個文件在操作系統(tǒng)中都有一個唯一的標識符——文件描述符。這些文件描述符用于指代進程當前使用的文件資源,并為操作系統(tǒng)提供對這些文件的管理和訪問。
- 作用:
- 文件描述符表用于將進程與打開的文件建立關聯(lián)。當一個進程打開文件時,操作系統(tǒng)會為該文件分配一個文件描述符,并將其存儲在進程的文件描述符表中。這個描述符使進程能夠通過標識符訪問文件,而不需要知道文件的具體位置或物理存儲,類似于一個特殊的指針
- 文件描述符表中的每個條目對應一個打開的文件,操作系統(tǒng)可以根據文件描述符來執(zhí)行文件的讀寫、關閉、定位等操作。
2.2.4進程狀態(tài)
PCB中同樣存儲著當前進程的狀態(tài),下面那是倆個常見重要的進程狀態(tài)。

2.2.4.1就緒狀態(tài)
進程已經準備好運行,但由于CPU正在執(zhí)行其他進程,因此處于等待中。操作系統(tǒng)將進程放入就緒隊列,等待調度器選擇該進程進行執(zhí)行。此時進程的所有資源(除了CPU)都已分配好。
2.2.4.2阻塞狀態(tài)
進程由于某些原因無法繼續(xù)執(zhí)行,此時進程不再占用CPU,而是處于阻塞狀態(tài)。阻塞狀態(tài)的進程會被移出CPU,直到它等待的條件滿足時才會變?yōu)榫途w狀態(tài)。
2.2.5進程優(yōu)先級
進程的優(yōu)先級是操作系統(tǒng)用來決定不同進程執(zhí)行順序的重要標準。它指示了一個進程相對于其他進程的重要性,系統(tǒng)會優(yōu)先選擇優(yōu)先級高的進程進行執(zhí)行。但其實在真正執(zhí)行時,優(yōu)先順序并不是定量的誰一定先執(zhí)行誰一定后執(zhí)行,而是一種定型的。
同樣,某個進程的優(yōu)先級也可以在任務管理器進行設置,但不知道為什么博主截不了圖,右鍵單機進程就會有這個選項啦。
2.2.6進程上下文
進程的上下文指的是操作系統(tǒng)在切換進程時需要保存和恢復的信息。每個進程在運行時都有自己的執(zhí)行狀態(tài),這些狀態(tài)決定了進程如何繼續(xù)執(zhí)行。操作系統(tǒng)通過上下文切換在不同進程之間進行切換時,保存并恢復這些信息。每次切換時必須保存和恢復這些信息,以確保每個進程能夠從中斷的地方繼續(xù)執(zhí)行。
2.2.7進程的記賬信息
統(tǒng)計每個進程在CPU上執(zhí)行了多久。如果該進程長時間沒分配到CPU資源,就會給這個進程傾斜一些CPU資源。
2.3CPU操作進程的方法
現(xiàn)在的電腦的CPU一般都有四核,八核,十六核,但我們打開任務管理器發(fā)現(xiàn)有成百上千個進程,那么電腦是如何同時操作這么多進程呢。
答案就是CPU對進程的操作的模式時分時復用:
分時復用:操作系統(tǒng)將CPU的時間分成若干個時間片,若一個進程的時間片用完了,操作系統(tǒng)會把CPU控制權交給下一個進程,保證多個進程交替執(zhí)行。
現(xiàn)代CPU的執(zhí)行模式:
并行執(zhí)行:
多個核同時處理多個進程
并發(fā)執(zhí)行:
單個核按照分時復用的原則處理多個進程
2.4什么是線程
線程是操作系統(tǒng)調度的最小單位,是進程(程序運行的實例)中的一個執(zhí)行單元。一個進程可以包含一個或多個線程,線程共享進程的資源(如內存、文件句柄),但每個線程都有自己的獨立執(zhí)行路徑、寄存器和棧空間。
當然我們沒有辦法直接看到線程,得通過一些工具才能查看。
2.4.1進程與線程
讓我們區(qū)分以下進程和線程并分析以下他們之間的聯(lián)系:
- 進程是線程的容器:一個進程可以包含一個或多個線程。線程依賴進程的存在,無法獨立于進程運行。
- 線程是進程的組成部分:線程負責在進程的上下文中執(zhí)行代碼,一個進程至少有一個主線程,用于啟動和管理程序的運行。
- 進程的生命周期包含線程的生命周期:當一個進程終止時,其所有線程也會終止。線程的存在和生命周期完全依附于所在進程。
2.4.2線程資源分布
類似于進程,線程也有其對應的屬性:
線程是進程中的執(zhí)行單元,多個線程共享進程的資源,如內存空間、文件描述符等
但每個線程也有獨立的資源,包括棧、程序計數(shù)器和寄存器。操作系統(tǒng)通過合理的資源分配和調度機制,確保多線程程序高效、安全地執(zhí)行。
2.5簡單實現(xiàn)線程
創(chuàng)建線程主要有倆種方式,一種是繼承Thread類,另一種是Runnable的接口,下文詳解。
2.5.1Thread類
操作步驟:
- 創(chuàng)建一個類并繼承
Thread類。 - 重寫
Thread類的run()方法,將線程執(zhí)行的具體任務寫在run()方法中。 - 創(chuàng)建線程對象并調用
start()方法啟動線程。
static class myThread extends Thread{
@Override
public void run() {
System.out.println(("線程已執(zhí)行"));
}
}
public static void main(String[] args) {
myThread myThread1 = new myThread();
myThread1.run();
}
2.5.2Runnable接口
操作步驟:
- 創(chuàng)建一個類并實現(xiàn)
Runnable接口。 - 重寫
Runnable接口中的run()方法,將線程任務寫在該方法中。 - 創(chuàng)建一個
Thread對象,將實現(xiàn)了Runnable接口的實例作為參數(shù)傳遞給Thread構造方法。 - 調用
Thread對象的start()方法啟動線程。
static class myRunable implements Runnable{
@Override
public void run() {
while(true){
System.out.println("線程正在被執(zhí)行");
}
}
}
public static void main(String[] args) {
myRunable myRunable1 = new myRunable();
Thread thread = new Thread(myRunable1);
thread.start();
while(true){
System.out.println("主函數(shù)正在被執(zhí)行");
}
}
我們可以發(fā)現(xiàn)此時倆個線程,一個是主函數(shù)的,另一個是新創(chuàng)立的,在交替執(zhí)行。
2.5.3區(qū)分start和run
這里可能有細心的小伙伴們觀察出來,第一個我們用了run方法,第二個我們用了start方法,那么這倆種方法有什么區(qū)別嗎:
start()方法- 用于啟動一個新的線程。
- 它會調用線程的底層實現(xiàn),告訴JVM創(chuàng)建一個新的線程。
- 然后,新線程會自動調用
run()方法中定義的邏輯。 start()使線程并發(fā)執(zhí)行。
run()方法- 是線程要執(zhí)行的任務邏輯。
- 如果直接調用
run()方法,并不會創(chuàng)建新線程,而是由當前線程執(zhí)行它。 - 相當于普通的同步方法調用。
2.5.4查看線程
想要查看線程的話我們需要去JDK中去尋找一個叫做jconsole的exe文件:

連接后就能查看線程了:

3.小結
到此這篇關于Java進程與線程及如何實現(xiàn)的文章就介紹到這了,更多相關Java進程與線程內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Springboot添加jvm監(jiān)控實現(xiàn)數(shù)據可視化
這篇文章主要介紹了Springboot添加jvm監(jiān)控實現(xiàn)數(shù)據可視化,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-04-04
Spring如何基于Proxy及cglib實現(xiàn)動態(tài)代理
這篇文章主要介紹了Spring如何基于Proxy及cglib實現(xiàn)動態(tài)代理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06
javaweb啟動時啟動socket服務端代碼實現(xiàn)
這篇文章主要介紹了javaweb啟動時啟動socket服務端代碼實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-11-11
詳解spring security之httpSecurity使用示例
這篇文章主要介紹了詳解spring security之httpSecurity使用示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08
解決@PathVariable參數(shù)接收不完整的問題
這篇文章主要介紹了解決@PathVariable參數(shù)接收不完整的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
關于java.lang.IncompatibleClassChangeError錯誤解決方案
最近開發(fā)中遇到類沖突報錯 java.lang.IncompatibleClassChangeError,所以下面這篇文章主要給大家介紹了關于java.lang.IncompatibleClassChangeError錯誤的解決方案,需要的朋友可以參考下2024-02-02
Java按順序提取Word內容的方法步驟(文本+數(shù)學公式)
本文分享通過Java POI庫解析Word試卷內容,將數(shù)學公式轉換為LaTeX并保持原有順序的方法,涉及XML文本提取、節(jié)點替換及文檔重構,解決公式位置錯亂問題,實現(xiàn)非結構化到結構化轉換,需要的朋友可以參考下2025-09-09
java 通過聚合查詢實現(xiàn)elasticsearch的group by后的數(shù)量
這篇文章主要介紹了java 通過聚合查詢實現(xiàn)elasticsearch的group by后的數(shù)量,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-12-12
Spring Boot企業(yè)常用的starter示例詳解
這篇文章主要給大家介紹了關于Spring Boot企業(yè)常用starter的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Spring Boot具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-12-12

