Java線程概念詳解

線程

在這里插入圖片描述

概念

1.程序:未解決某種問題,使用計算機語言編寫的一些列指令(代碼)的集合

2.進程:正在運行的程序(被加載到內存中),是操作系統進行資源分配的最小單位

3.線程:進程可以進一步細化為線程(比進程更小)且線程是隸屬于進程的,是操作系統執行的最小的執行單元 也是cpu進行任務調度的最小單位

  • 如 :運行的QQ也是一個進程,操作系統就會為這個進程分配資源 一個聊天窗口就是一個線程,線程隸屬于進程

tips:早期是沒有線程的,是以進程為單位執行的,進程的單位比較大,當一個進程運行時,其他進程就不能執行了,所以后來,將進程中的多個任務細化為線程,cpu的執行單位,也是從進程進化為更小的線程

總結

  1. 一個進程可以包含多個線程
  2. 一個線程只能隸屬于一個進程,線程不能脫離進程單獨獨立運行
  3. 一個進程中至少有一個線程,即主線程,javamian方法就是用來啟動主線程
  4. 在主線程中可以創建并啟動其他線程,所有線程都共享進程的內存資源
  5. 所有線程都共享進程資源

Thread類

JavaThread表示線程,提供了許多的方法,來對線程的控制,可以通過繼承Thread 類來實現線程

Thread常用方法

  • Thread.currentThread();
    • 獲取當前運行的線程
  • run();
    • 線程要執行的任務
  • start();
    • 啟動Java線程
  • setName(String name);
    • 設置線程名字
  • (String)getName();
    • 獲取線程名字
  • getPriority();
    • 獲取線程優先級
  • setPriority();
    • 設置線程優先級 1~10一般線程默認優先 5
  • sleep(long ms);
    • 設置線程休眠
  • join();
    • 讓其他線程等待這個線程結束后,其他線程再執行

Thread構造方法

  • new Thread(Runnable runnable);
    • 接受一個任務對象
  • new Thread(Runnable runnable,String name);
    • 接受一個對象 并為對象設置名字

使用上面方法進行實例

線程1
public class MyThread extends Thread{//重寫run方法,在run中執行我們要執行的方法@Overridepublic void run() {for(int i=0;i<10000;i++){System.out.println("循環main"+i);}}}
線程2
public class MyThread2 extends Thread {@Overridepublic void run() {for(int i=0;i<10000;i++){System.out.println("循環main2"+i);}}
}
public class 線程 {public static void main(String[] args) {for(int i=0;i<10000;i++){System.out.println("循環1 "+i);}for(int i=0;i<10000;i++){System.out.println("循環2 "+i);}for(int i=0;i<10000;i++){System.out.println("循環3 "+i);}for(int i=0;i<10000;i++){System.out.println("循環4 "+i);}/*這樣不管怎么執行都是單線程,從上到下依次執行,所以如果想在java程序中有幾件不想管的事件同時執行可以在java中創建線程,把一些需要執行的任務放在線程中執行,這樣就擁有讓cup執行的權利*/MyThread myThread = new MyThread();//調用start方法讓程序多線程進行,重寫run方法但不能調用run,不然只是普通方法的調用,依然是單線程myThread.start();MyThread2 myThread2 = new MyThread2();myThread2.start();}}

image-20231207203645612

觀察結果 可知 MyThreadMyThread2是同時進行的

Runnable接口

Java中我們也可以實現Runnable接口來進行對線程的實現

思路.

  • 創建一個類 實現Runnable接口 重寫run方法

  • 在main函數使用Thread構造方法傳入Runnable對象

  • public class MyTask implements Runnable{@Overridepublic void run() {for(int i=0;i<10;i++){System.out.println("啊");}}
    }
    
  • MyTask myTask = new MyTask();//創建一個線程Thread thread = new Thread(myTask);
    

Callable接口

Java中也可以實現Callable接口 重寫 call()方法 來對線程的實現

思路.

  • 重寫call()方法 call()方法有返回值 可以拋出異常,還可以處理不同類型
  • 依然使用Thread構造方法來創建一個線程

關于線程的其他概念

線程生命周期

從線程到銷毀期間經歷五個狀態

image-20231029190539052

守護線程(也是線程的一種)

  • setDaemon();如果一個**線程守護線程**,那么它會等待java中其他線程任務結束后,自動終止
  • 守護線程是為其他線程提供服務的,eg:jvm中的垃圾回收機制,就是一個守護線程

多線程

在一個應用程序中,存在多個線程,不同線程可以并行的執行任務

*操作系統線程任務調度算法

  1. 先來先服務調度算法
  2. 短作業優先調度算法
  3. 優先級調度算法
  4. 高響應比優先調度算法
  5. 時間片輪轉調度算法
  6. 多級反饋隊列調度算法(集合前幾種算法的優點)

對線程進行加鎖

分析

  • 多線程的優點
    • 提高程序的處理能力
    • 提高CPU的 利用率
  • 缺點
    • 線程也是需要占用內存資源和CPU資源
    • 多個線程對同一個共享資源進行訪問,會出現線程安全問題

對于內存資源與CPU資源我們可以通過不斷增加內存來解決

對于線程安全問題 我們則需要對 線程進行加鎖

synchronized

synchronized 修飾代碼塊需要加一個同步對象 synchronized(同步對象)

同步對象要求

  • 多線程用到的對象必須是同一個對象
  • 可以是java類中任何類對象.
  • 作用:用來記錄有沒有線程進入到同步代碼塊中

修飾方法

  • 鎖不需要我們提供,會默認提供鎖對象
  • synchronized如果修飾的是非靜態方法,鎖的對象是this
  • 如果是靜態方法,鎖的對象是Class的對象 (一個類只能有一個對象)

修飾代碼塊例子

package day17;public class PrintNums implements Runnable{//實現線程的交替打印int num=100;Object object = new Object();@Overridepublic void run() {while(true){synchronized (object){object.notify();//喚醒線程if(num==0){break;}System.out.println(Thread.currentThread().getName()+"."+num+".");num--;try {object.wait();//線程等待} catch (InterruptedException e) {e.printStackTrace();}}}}
}
package day17;public class TestPrintNums {public static void main(String[] args) {PrintNums printNums = new PrintNums();Thread t1 = new Thread(printNums,"1");Thread t2 = new Thread(printNums,"2");Thread t3 = new Thread(printNums,"3");t1.start();t2.start();t3.start();}
}

image-20231207211850022

于是我們實現了交替打印 每次只能進入一個線程

修飾方法(同步對象會有默認的)

  1. 鎖不需要我們提供,會默認提供對象鎖
  2. synchronized如果修飾的是非靜態方法,鎖的對象是this

? synchronized如果修飾的是靜態方法,鎖的對象是類的Class對象,一個類只有 一個對象

  • 如果是非靜態方法,那么同步對象是this(如果是非靜態對象,我們可以使用Runnable創建線程方法)

  • 如果是靜態方法,所得對象是當前類的Class對象

  • 當前類的Class對象:一個類加載到內存后會為這個類創建唯一的Class類的對象

  • Class類實例表示正在運行的Java應用程序中的類和接口

  • 修飾靜態方法
    public class SellTicket extends Thread {static int counts = 10;//10張票static Object object = new Object();@Overridepublic void run() {while (counts > 0) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}sellTicket();}}public static synchronized void sellTicket() {if(counts>0){System.out.println(Thread.currentThread().getName()+"買了"+counts+"張票");--counts;}}
    }
    public class Test {public static void main(String[] args) {SellTicket t1 = new SellTicket();t1.setName("窗口1");SellTicket t2 = new SellTicket();t2.setName("窗口2");t1.start();t2.start();}
    }
    

    image-20231209231353289

  • 修飾非靜態方法
    public class SellTickets2 implements Runnable{int t=20;//票數@Overridepublic void run() {while(t>0){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}sell2();}}public synchronized void sell2(){if(t>0){System.out.println(Thread.currentThread().getName()+"買了"+t+"張票");--t;}}
    }public class Test2 {public static void main(String[] args) {SellTickets2 sellTickets2 = new SellTickets2();Thread t1 = new Thread(sellTickets2,"窗口1");Thread t2 = new Thread(sellTickets2,"窗口2");t1.start();t2.start();}
    }
    

    image-20231209231446179

ReentrantLock類加鎖

  • 只能對某一代碼塊進行加鎖,不能對整個方法加鎖
  • 加鎖方法如下
ReentrantLock r = new ReentrantLock();//創建 ReentrantLock對象
r.lock();<---------|//加鎖|.............    |------被鎖部分(一次只進去一個線程)|
r.unlock();<-------|//解鎖

tips:r.unlock();最好寫在finally{};代碼塊中,保證發生異常時,也能夠解鎖;

synchronized與ReentrantLock的區別

  1. synchronized是一個關鍵字,ReentrantLock是一個類

  2. synchronized修飾代碼塊和方法,ReentrantLock只能修飾代碼塊

  3. synchronized可以隱式的加鎖和釋放鎖,運行出現異常可以自動釋放鎖

    ReentrantLock需要手動加鎖和釋放鎖,建議在finally代碼中釋放鎖

常用的三個方法 wait ``notify notifyAll

  • wait();方法使當前線程進入等待狀態,直到另一個線程調用該對象的notify()notifyAll()方法來喚醒它

  • notify();方法喚醒在該對象上調用wait()方法進入等待狀態的一個線程,如果有多個線程在等待,則只會喚醒其中一個線程。

  • notifyAll();方法喚醒在該對象上調用wait()方法進入等待狀態的所有線程。

    ? tips:1.都是Object類中定義的方法

    ? 2.三個方法必須在同步代碼塊中使用

    ? 3.這三個方法必須通過為鎖的對象調用

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/210944.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/210944.shtml
英文地址,請注明出處:http://en.pswp.cn/news/210944.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CleanMyMac X2024免費許可證(激活教程)

CleanMyMac X是一款流行的系統優化工具&#xff0c;專為Mac用戶設計。它可以幫助用戶清理Mac系統中的垃圾文件、卸載不需要的程序、加速Mac性能以及保護Mac系統的安全。 一、簡介 CleanMyMac X是一款功能強大的系統優化工具&#xff0c;它可以幫助用戶清理Mac系統中的垃圾文件…

優麒麟ubuntukylin安裝UE4.27.2

優麒麟ubuntukylin安裝UE4.27.2 在&#xff08;國產&#xff09;優麒麟 ubuntukylin Linux平臺上編譯測試安裝虛幻引擎。 優麒麟系統 這里選擇的是官方增強版 https://www.ubuntukylin.com/downloads/ 同樣的可以選擇對應的Ubuntu22.04 LTS&#xff0c;唯一的區別就是優麒麟…

【精選】SpringMVC簡介及其執行流程,參數獲取方式

SpringMVC簡介 MVC模型 MVC全稱Model View Controller&#xff0c;是一種設計創建Web應用程序的模式。這三個單詞分別代表Web應用程序的三個部分&#xff1a; Model&#xff08;模型&#xff09;&#xff1a;指數據模型。用于存儲數據以及處理用戶請求的業務邏輯。在Web應用中&…

采用NSD評估ADC性能

概要 評估采樣器的傳統性能指標SNR、SFDR和ENOB最早被用于二戰時期,這些性能指標使用于具有通道選擇性和低通采樣使用的ADC,并不適用于近些年的射頻直采ADC,因此需要引入更合適的噪聲譜密度NSD(Noise Spectrum Density)指標來評估噪聲性能。 傳統技術指標的含義 無雜散…

async函數和await表達式

async函數 函數的返回值為promise對象 &#xff08;Promise介紹&#xff09;promise對象的結果由async函數執行的返回值決定&#xff0c;如果對象內返回非promise對象&#xff0c;比如字符串&#xff0c;那么返回結果是成功的promise對象&#xff0c;如果返回的是promise對象&…

Photoshop Circular Text

Ctrl N 新增 現學現賣

uniapp移動端懸浮按鈕(吸附邊緣)

Uniapp移動端懸浮按鈕可以通過CSS實現吸附邊緣的效果。具體實現步驟如下&#xff1a; html&#xff1a; <movable-area class"movable-area"><movable-view class"movable-view" :position"position" :x"x" :y"y"…

HarmonyOS4.0從零開始的開發教程06常用基礎組件

HarmonyOS&#xff08;四&#xff09;常用基礎組件 1 組件介紹 組件&#xff08;Component&#xff09;是界面搭建與顯示的最小單位&#xff0c;HarmonyOS ArkUI聲明式開發范式為開發者提供了豐富多樣的UI組件&#xff0c;我們可以使用這些組件輕松的編寫出更加豐富、漂亮的界…

代碼隨想錄-刷題第二十二天

235.二叉搜索樹的最近公共祖先 題目鏈接&#xff1a;235. 二叉搜索樹的最近公共祖先 思路&#xff1a;根據二叉搜索樹的特性&#xff0c;只需要判斷當前節點是否在[p,q]范圍內就可以&#xff0c;如果在這個范圍里&#xff0c;說明當前節點就是其最近公共祖先。 class Soluti…

C語言進階之路之結構體、枚舉關卡篇

目錄 一、學習目標 二、組合數據類型-結構體 結構體基本概念 結構體的聲明&#xff1a; 小怪實戰 結構體初始化 指定成員初始化的好處&#xff1a; 結構體成員引用 結構體指針與數組 關卡BOOS 三、結構體的尺寸 CPU字長 地址對齊 結構體的M值 可移植性 四、聯合體…

Java 使用冒號的七種方式

在 Java 中&#xff0c;冒號字符&#xff08;:&#xff09;用于不同的上下文&#xff0c;并根據上下文的不同而具有不同的含義。 以下是 Java 中冒號的一些常用用法&#xff1a; 1、三元運算符 冒號在三元運算符 (? :) 中用作條件、條件為真時要執行的表達式和條件為假時要執…

計算機視覺 基于Open3D了解用于網格和點云鄰域分析的KD樹和八叉樹

一、簡述 距離計算和鄰域分析是理解網格和點云的形狀、結構和特征的重要工具。我們這里要基于一些3D庫來提取基于距離的信息并將其可視化。 與深度圖或體素相比,點云和網格表示 3D 空間中的非結構化數據。點由它們的 (X, Y, Z) 坐標表示,在 3D 空間中可能彼此靠近的兩…

Python數據科學視頻講解:數據清洗、特征工程和數據可視化的注意事項

1.6 數據清洗、特征工程和數據可視化的注意事項 視頻為《Python數據科學應用從入門到精通》張甜 楊維忠 清華大學出版社一書的隨書贈送視頻講解1.6節內容。本書已正式出版上市&#xff0c;當當、京東、淘寶等平臺熱銷中&#xff0c;搜索書名即可。內容涵蓋數據科學應用的全流程…

深入理解HTTP協議中的GET、POST、DELETE和PUT方法

在Web開發中&#xff0c;我們經常需要與服務器進行交互&#xff0c;以獲取或發送數據。為了實現這一目標&#xff0c;我們使用HTTP協議。HTTP協議是一種無狀態的、應用層的協議&#xff0c;它定義了客戶端和服務器之間的通信方式。在HTTP協議中&#xff0c;有四種常用的請求方法…

MN316 OpenCPU丨HTTP使用介紹

HTTP&#xff08;Hyper Text Transfer Protocol&#xff09;即超文本傳輸協議&#xff0c;是一個簡單的請求-響應協議&#xff0c;通常運行在TCP之上&#xff0c;它指定了客戶端可能發送給服務器消息類型以及得到什么類型響應。HTTPS&#xff08;Hyper Text Transfer Protoc…

uniapp使用v-html調用接口,富文本圖片 視頻自適應大小

前端獲取到后臺數據 不做處理 就會出現下面問題 圖片 視頻超出視圖顯示不全 處理 //info 是富文本 <view v-ifinfo v-htmlreplaceWhite(info)></view>調用下面方法 replaceWhite(html) { // 處理富文本默認圖片&#xff0c;視頻大小let newContent html.replace…

Nestjs聯合Typeorm操作Mysql數據庫

創建項目 // 安裝腳手架(只需要安裝一次,因為這個是全局的) npm i -g nestjs/cli // 創建項目 nest new project-name // (該過程有個選擇包管理工具的,我選的yarn)啟動項目 yarn run start:dev // 可以在瀏覽器訪問localhost:3000 輸出helloWorld安裝typeorm,mysql2和nestj…

藍橋小白賽1

&#x1f469;?&#x1f3eb; 地址 1. 蘑菇炸彈 &#x1f469;?&#x1f3eb; 蘑菇炸彈 &#x1f389; AC code import java.util.Scanner;public class Main {public static void main(String[] args){Scanner sc new Scanner(System.in);int n sc.nextInt();int[] a …

d8week17

Week7 lec17 TVD去asscess model &#xff08;本質 距離加權平均&#xff09;text 11.2A New Statistic: The Distance between Two Distributions text-11.11.1 數據拿到手&#xff0c;套路操作 -- 看hist分布2 total variation distance lec18lec19 lec17 TVD去asscess model…

使用NCNN在華為M5部署Yolov5

使用NCNN在華為M5平板部署Yolov5 一、NCNN二、下載解壓NCNN三、下載ncnn-android-yolov5工程四、下載Android Studio[前提已經配置了jdk版本]1、安裝NDK、Cmske&#xff0c;這個必須要安裝&#xff0c;2、安裝Android 五、構建工程六、修改源碼七、重新ysnc project八、安裝APP…