多線程到底重不重要?

我們先說一下為什么要講多線程和高并發?

原因是,你想拿到一個更高的薪水,在面試的時候呈現出了兩個方向的現象:

第一個是上天

  • 項目經驗
  • 高并發 緩存 大流量 大數據量的架構設計

第二個是入地

  • 各種基礎算法,各種基礎的數據結構
  • JVM OS 線程 IO等內容

多線程和高并發,就是入地里面的內容。

基本概念

我們先從線程的基本概念開始,給大家復習一下,不知道有多少同學是基礎不太好,說什么是線程都不知道的,如果這樣的話,花時間去補初級內容的課。

什么是叫一個進程? 什么叫一個線程?

Program app ->QQ.exe

**進程:**做一個簡單的解釋,你的硬盤上有一個簡單的程序,這個程序叫QQ.exe,這是一個程序,這個程序是一個靜態的概念,它被扔在硬盤上也沒人理他,但是當你雙擊它,彈出一個界面輸入賬號密碼登錄進去了,OK,這個時候叫做一個進程。進程相對于程序來說它是一個動態的概念

**線程:**作為一個進程里面最小的執行單元它就叫一個線程,用簡單的話講一個程序里不同的執行路徑就叫做一個線程

示例:什么叫做線程

package com.mashibing.juc.c_000;
import java.util.concurrent.TimeUnit;
public class T01_WhatIsThread {	private static class T1	extends Thread {@Override														public void run() {for(int i=0; i<10; i++) {try {TimeUnit.MICROSECONDS.sleep(1);} catch (InterruptedException e) { e.printStackTrace();}System.out.println("T1");}}}public static void main(String[] args) {//new T1().run();new T1().start();for(int i=0; i<10; i++) {try {TimeUnit.MICROSECONDS.sleep(1);} catch (InterruptedException e) { e.printStackTrace();}System.out.println("main");}}
}

觀察上面程序的數據結果,你會看到字符串“T1”和“Main”的交替輸出,這就是程序中有兩條不同的執行路徑在交叉執行,這就是直觀概念上的線程,概念性的東西,理解就好,沒有必要咬文嚼字的去背文字的定義。

創建線程的幾種方式

package com.mashibing.juc.c_000;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;public class T02_HowToCreateThread {static class MyThread extends Thread {@Overridepublic void run() {System.out.println("Hello MyThread!");}
}static class MyRun implements Runnable {@Overridepublic void run() {System.out.println("Hello MyRun!");}
}static class MyCall implements Callable<String> {@Overridepublic String call() {System.out.println("Hello MyCall"); return "success";}
}//啟動線程的5種方式public static void main(String[] args) {new MyThread().start();new Thread(new MyRun()).start(); new Thread(()->{System.out.println("Hello Lambda!");}).start();Thread t = new Thread(new FutureTask<String>(new MyCall()));t.start();ExecutorService service = Executors.newCachedThreadPool(); service.execute(()->{System.out.println("Hello ThreadPool");});service.shutdown();
}}

分享一道面試題

請你告訴我啟動線程的三種方式 ?

你說第一個:new Thread().start(); 第二個: new Thread(Runnable).start() 這沒問題 ;那第三個呢,要回答線程池也是用的這兩種之一,他這么問有些吹毛求疵的意思,你就可以說通過線程池也可以啟動一個新的線程 3:Executors.newCachedThreadPool()或者FutureTask + Callable

我們來認識幾個線程的方法

package com.mashibing.juc.c_000; 
public class T03_Sleep_Yield_Join { public static void main(String[] args) { //testSleep(); //testYield(); testJoin();} /*Sleep,**意思就是睡眠,當前線程暫停一段時間讓給別的線程去運行。**Sleep**是怎么復活的?由你的睡眠時間而定,等睡眠到規定的時間自動復活***/ static void testSleep() { new Thread(()->{ for(int i=0; i<100; i++) { System.out.println("A" + i); try { Thread.sleep(500);//TimeUnit.Milliseconds.sleep(500)} catch (InterruptedException e) { e.printStackTrace();}}}).start();}/*Yield,就是當前線程正在執行的時候停止下來進入等待隊列,回到等待隊列里在系統的調度算法里頭呢還是依然有可能把你剛回去的這個線程拿回來繼續執行,當然,更大的可能性是把原來等待的那些拿出一個來執行,所以yield的意思是我讓出一下CPU,后面你們能不能搶到那我不管*/static void testYield() {new Thread(()->{for(int i=0; i<100; i++) {System.out.println("A" + i);if(i%10 == 0) Thread.yield();}}).start();new Thread(()->{for(int i=0; i<100; i++) {System.out.println("------------B" + i);if(i%10 == 0) Thread.yield();}}).start();
}/*join, 意思就是在自己當前線程加入你調用Join的線程(),本線程等待。等調用的線程運行完了,自己再去執行。t1和t2兩個線程,在t1的某個點上調用了t2.join,它會跑到t2去運行,t1等待t2運行完畢繼續t1運行(自己join自己沒有意義) */static void testJoin() {Thread t1 = new Thread(()->{for(int i=0; i<100; i++) {System.out.println("A" + i);try {Thread.sleep(500);//TimeUnit.Milliseconds.sleep(500)} catch (InterruptedException e) {e.printStackTrace();}}});Thread t2 = new Thread(()->{try {t1.join();} catch (InterruptedException e) { e.printStackTrace();}for(int i=0; i<100; i++) {System.out.println("A" + i);try {Thread.sleep(500);//TimeUnit.Milliseconds.sleep(500)} catch (InterruptedException e) { e.printStackTrace();}}});t1.start();t2.start();}
}

線程狀態

常見的線程狀態有六種:

當我們new一個線程時,還沒有調用start()該線程處于新建狀態

線程對象調用 start()方法時候,他會被線程調度器來執行,也就是交給操作系統來執行了,那么操作系統來執行的時候,這整個的狀態叫Runnable,Runnable內部有兩個狀態**(1)Ready就緒狀態/(2)Running運行狀態**。就緒狀態是說扔到CPU的等待隊列里面去排隊等待CPU運行,等真正扔到CPU上去運行的時候才叫Running運行狀態。(調用yiled時候會從Running狀態跑到Ready狀態去,線程配調度器選中執行的時候又從Ready狀態跑到Running狀態去)

如果你線程順利的執行完了就會進去**(3)Teminated****結束狀態**,(需要注意Teminated完了之后還可不可以回到new狀態再調用start?這是不行的,完了這就是結束了)

在Runnable這個狀態里頭還有其他一些狀態的變遷**(4)TimedWaiting等待、(5)Waiting等待、(6)Blocked阻塞**,在同步代碼塊的情況就下沒得到鎖就會阻塞狀態,獲得鎖的時候是就緒狀態運行。在運行的時候如果調用了o.wait()、t.join()、LockSupport.park()進入Waiting狀態,調用o.notify()、o.notifiAll()、LockSupport.unpark()就又回到Running狀態。TimedWaiting按照時間等待,等時間結束自己就回去了,Thread.sleep(time)、o.wait(time)、t.jion(time)、LockSupport.parkNanos()、LockSupport.parkUntil()這些都是關于時間等待的方法。

問題1:哪些是JVM管理的?哪些是操作系統管理的?

上面這些狀態全是由JVM管理的,因為JVM管理的時候也要通過操作系統,所以呢,那個是操作系統和那個是JVM他倆分不開,JVM是跑在操作系統上的一個普通程序 。

問題2:線程什么狀態時候會被掛起?掛起是否也是一個狀態?

Running的時候,在一個cpu上會跑很多個線程,cpu會隔一段時間執行這個線程一下,在隔一段時間執行那個線程一下,這個是cpu內部的一個調度,把這個狀態線程扔出去,從running扔回去就叫線程被掛起,cpu控制它。

來看一下ThraedState這段代碼。

package com.mashibing.juc.c_000;
public class T04_ThreadState {static class MyThread extends Thread {@Overridepublic void run() {System.out.println(this.getState());for(int i=0; i<10; i++) {try {Thread.sleep(500);} catch (InterruptedException e) { e.printStackTrace();}System.out.println(i);}}}public static void main(String[] args) {Thread t = new MyThread();//怎么樣得到這個線程的狀態呢?就是通過getState()這個方法System.out.println(t.getState());//他是一個new狀態t.start();//到這start完了之后呢是Runnable的狀態try {t.join();} catch (InterruptedException e) { e.printStackTrace();}//然后join之后,結束了是一個Timenated狀態System.out.println(t.getState());}
}

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

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

相關文章

AI大模型測試用例生成平臺

AI測試用例生成平臺 項目背景技術棧業務描述項目展示項目重難點 項目背景 針對傳統接口測試用例設計高度依賴人工經驗、重復工作量大、覆蓋場景有限等行業痛點&#xff0c;基于大語言模型技術實現接口測試用例智能生成系統。 技術棧 LangChain框架GLM-4模型Prompt Engineeri…

【論文筆記】Contrastive Learning for Compact Single Image Dehazing(AECR-Net)

文章目錄 問題創新網絡主要貢獻Autoencoder-like Dehazing NetworkAdaptive Mixup for Feature PreservingDynamic Feature Enhancement1. 可變形卷積的使用2. 擴展感受野3. 減少網格偽影4. 融合空間結構信息 Contrastive Regularization1. 核心思想2. 正樣本對和負樣本對的構建…

異步加載錯誤如何解決

首先是 提供兩張圖 如果數據過多的情況下我在所內和住家形式頻繁的來回切換 導致數據展示的不一樣 大家是不是有這樣的問題 這個是導致了數據展示有問題的情況 住家的情況本來是沒有幾層的 下面我幫大家解決一下 // 防止異步延遲 const Noop () > { } const lhl (resDa…

編譯支持 RKmpp 和 RGA 的 ffmpeg 源碼

一、前言 RK3588 支持VPU硬件解碼&#xff0c;需要rkmpp進行調用&#xff1b;支持2D圖像加速&#xff0c;需要 RGA 進行調用。 這兩個庫均能通過 ffmpeg-rockchip 進行間接調用&#xff0c;編譯時需要開啟對應的功能。 二、依賴安裝 編譯ffmpeg前需要編譯 rkmpp 和 RGA&#xf…

數據科學/數據分析暑期實習題目匯總

文章目錄 1. 孤立森林算法2. python私有屬性代碼解釋1. 類的定義2. 構造方法 `__init__`3. 創建類的實例4. 訪問私有屬性總結python列表拷貝代碼示例與分析內存地址不同的原因驗證對其中一個列表修改不會影響另一個列表記錄一些值得記錄的題目。 1. 孤立森林算法 異常點判斷的…

Java多線程與高并發專題——原子類和 volatile、synchronized 有什么異同?

原子類和 volatile異同 首先&#xff0c;通過我們對原子類和的了解&#xff0c;原子類和volatile 都能保證多線程環境下的數據可見性。在多線程程序中&#xff0c;每個線程都有自己的工作內存&#xff0c;當多個線程訪問共享變量時&#xff0c;可能會出現一個線程修改了共享變…

207、【圖論】孤島的總面積

題目 思路 相比于 206、【圖論】島嶼數量&#xff0c;就是在這個代碼的基礎上。先遍歷邊界&#xff0c;將邊界連接的島嶼變為0&#xff0c;然后再計算一遍當前為1的島嶼面積。 代碼實現 import collectionsn, m list(map(int, input().split())) graph []for _ in range(n…

大模型最新面試題系列:微調篇之微調基礎知識

一、全參數微調&#xff08;Full-Finetune&#xff09; vs 參數高效微調&#xff08;PEFT&#xff09;對比 1. 顯存使用差異 全參數微調&#xff1a;需存儲所有參數的梯度&#xff08;如GPT-3 175B模型全量微調需約2.3TB顯存&#xff09;PEFT&#xff1a;以LoRA為例&#xff…

【GPT入門】第21課 langchain核心組件

【GPT入門】第21課 langchain核心組件 1. langchain 核心組件2.文檔加載器 Document loader3.文檔處理器3.1 langchain_text_splitters3.3 FAISS向量數據庫和向量檢索主要作用應用場景4. 對話歷史管理1. langchain 核心組件 模型 I/O 封裝 LLMs:大語言模型 Chat Models:一般…

應急響應靶機練習-Linux2

1.背景 前景需要&#xff1a;看監控的時候發現webshell告警&#xff0c;領導讓你上機檢查你可以救救安服仔嗎&#xff01;&#xff01; 挑戰內容&#xff1a; &#xff08;1&#xff09;提交攻擊者IP &#xff08;2&#xff09;提交攻擊者修改的管理員密碼(明文) &#xff08;…

分享一個免費的CKA認證學習資料

關于CKA考試 CKA&#xff08;Certified Kubernetes Administrator&#xff09;是CNCF基金會&#xff08;Cloud Native Computing Foundation&#xff09;官方推出的Kubernetes管理員認證計劃&#xff0c;用于證明持有人有履行Kubernetes管理的知識&#xff0c;技能等相關的能力…

【PTA題目解答】7-2 簡化的插入排序(15分)

1.題目 本題要求編寫程序&#xff0c;將一個給定的整數插到原本有序的整數序列中&#xff0c;使結果序列仍然有序。 輸入格式&#xff1a; 輸入在第一行先給出非負整數N&#xff08;<10&#xff09;&#xff1b;第二行給出N個從小到大排好順序的整數&#xff1b;第三行給…

【最新】 ubuntu24安裝 1panel 保姆級教程

系統&#xff1a;ubuntu24.04.1 安裝軟件 &#xff1a;1panel 第一步&#xff1a;更新系統 sudo apt update sudo apt upgrade 如下圖 第二步&#xff1a;安裝1panel&#xff0c;運行如下命令 curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o …

UE4-UE5虛幻引擎,前置學習一--Console日志輸出經常崩潰,有什么好的解決辦法

有些差異 這么牛逼的引擎&#xff0c;居然有這種入門級別的問題&#xff0c;一觸發清理&#xff0c;大概率(80%)會崩潰 無論虛幻5還是UE4都有這個問題&#xff0c;挺煩人的 實在忍不了了&#xff0c;這次&#xff0c;今天 就想問問有什么好的處理方法么&#xff1f;&#x…

【微服務】Nacos 配置動態刷新(簡易版)(附配置)

文章目錄 1、實現方法2、配置依賴 yaml3、驗證效果 1、實現方法 環境&#xff1a;Nacos、Java、SpringBoot等 主要是在boostrap.yaml中的data-id屬性下配置refresh:true來實現動態更新 2、配置依賴 yaml 具體的版本參考官方的說明&#xff1a;官方版本說明 <!--讀取boo…

設計模式之備忘錄設計模式

備忘錄設計模式&#xff08;Memento Pattern&#xff09; 在不破壞封閉的前提下&#xff0c;捕獲一個對象的內部狀態&#xff0c;保存對象的某個狀態&#xff0c;以便在適當的時候恢復對象&#xff0c;又叫做快照模式&#xff0c;屬于行為模式備忘錄模式實現的方式需要保證被保…

pytest 框架學習總結

視頻&#xff1a;pytest01-快速上手_嗶哩嗶哩_bilibili 資料&#xff1a;pytest 框架 - 白月黑羽 基于 Python 語言的自動化測試框架 最知名的 有如下 3 款unittest、pytest、robotframework 前兩款框架主要&#xff08;或者說很大程度上&#xff09;是 聚焦 在 白盒單元測試…

Day16:最小的k個數

倉庫管理員以數組 stock 形式記錄商品庫存表&#xff0c;其中 stock[i] 表示對應商品庫存余量。請返回庫存余量最少的 cnt 個商品余量&#xff0c;返回 順序不限。 示例 1&#xff1a; 輸入&#xff1a;stock [2,5,7,4], cnt 1 輸出&#xff1a;[2]示例 2&#xff1a; 輸入…

【最后203篇系列】016 Q201架構思考

前言 Q200已經達到了我既定的目標&#xff0c;在最近的3個月&#xff0c;我需要進一步完善&#xff0c;達到可以試產的程度。 在這個過程當中&#xff0c;許多知識和體會一直在變。 qtv200到目前&#xff0c;雖然通過習慣(每晚運行離線策略和比對)方式維持了注意力的集中&…

音視頻入門基礎:RTP專題(20)——通過FFprobe顯示RTP流每個packet的信息

通過FFprobe命令&#xff1a; ffprobe -protocol_whitelist "file,rtp,udp" -of json -show_packets XXX.sdp 可以顯示SDP描述的RTP流每個packet&#xff08;數據包&#xff09;的信息&#xff1a; 對于RTP流&#xff0c;上述的“packet”&#xff08;數據包&#…