Java多線程與高并發

1、什么是進程?什么是線程?

進程:進程是程序的基本執行實體;另外一種解釋是進程是一個應用程序(1個進程是一個軟件)。
線程:線程是操作系統能夠進行運算調度的最下單位。它被包含在進程之中,是進程中的實際運作單位;是一個進程中的執行場景/執行單元。

注意:。一個進程可以啟動多個線程

eg.
對于java程序來說,當在DOS命令窗口中輸入:
java HelloWorld 回車之后。會先啟動JVM,而JVM就是一個進程。

JVM再啟動一個主線程調用main方法(main方法就是主線程)。
同時再啟動一個垃圾回收線程負責看護,回收垃圾。

最起碼,現在的java程序中至少有兩個線程并發,一個是 垃圾回收線程,一個是 執行main方法的主線程。

2、進程和線程是什么關系?

進程:可以看做是現實生活當中的公司。

線程:可以看做是公司當中的某個員工。

注意:進程A和進程B的 內存獨立不共享。

魔獸游戲是一個進程
酷狗音樂是一個進程
這兩個進程是獨立的,不共享資源。

線程A和線程B是什么關系?

在java語言中:
線程A和線程B,堆內存 和 方法區 內存共享。但是 棧內存 獨立,一個線程一個棧。

eg.

假設啟動10個線程,會有10個棧空間,每個棧和每個棧之間,互不干擾,各自執行各自的,這就是多線程并發。

eg.

火車站,可以看做是一個進程。
火車站中的每一個售票窗口可以看做是一個線程。
我在窗口1購票,你可以在窗口2購票,你不需要等我,我也不需要等你。所以多線程并發可以提高效率。


java中之所以有多線程機制,目的就是為了 提高程序的處理效率。

3、思考一個問題

使用了多線程機制之后,main方法結束,是不是有可能程序也不會結束?

main方法結束只是主線程結束了,主棧空了,其它的棧(線程)可能還在壓棧彈棧。

4、分析一個問題

對于單核的CPU來說,真的可以做到真正的多線程并發嗎?

對于多核的CPU電腦來說,真正的多線程并發是沒問題的。4核CPU表示同一個時間點上,可以真正的有4個進程并發執行。

單核的CPU表示只有一個大腦:
不能夠做到真正的多線程并發,但是可以做到給人一種“多線程并發”的感覺。

對于單核的CPU來說,在某一個時間點上實際上只能處理一件事情,但是由于CPU的處理速度極快,多個線程之間頻繁切換執行,給別人的感覺是:多個事情同時在做!!!

eg.

線程A:播放音樂

線程B:運行魔獸游戲

線程A和線程B頻繁切換執行,人類會感覺音樂一直在播放,游戲一直在運行,
給我們的感覺是同時并發的。(因為計算機的速度很快,我們人的眼睛很慢,所以才會感覺是多線程!)


5、什么是真正的多線程并發?

t1線程執行t1的。
t2線程執行t2的。
t1不會影響t2,t2也不會影響t1。這叫做真正的多線程并發。

關于線程對象的生命周期(附圖)?★★★★★

  1. 新建狀態
  2. 就緒狀態
  3. 運行狀態
  4. 阻塞狀態
  5. 死亡狀態

在這里插入圖片描述

線程構造方法

構造方法名備注
Thread()
Thread(String name)name為線程名字
創建線程第二種方式
Thread(Runnable target)
Thread(Runnable target, String name)name為線程名字

6、java語言中,實現線程有兩種方式

第一種方式:

編寫一個類,直接 繼承 java.lang.Thread,重寫 run方法。

  1. 怎么創建線程對象? new繼承線程的類。
  2. 怎么啟動線程呢? 調用線程對象的 start() 方法。

偽代碼:

// 定義線程類
public class MyThread extends Thread{public void run(){}
}
// 創建線程對象
MyThread t = new MyThread();
// 啟動線程。
t.start();

eg:

@SpringBootTest
public class Xiexingguo2ApplicationTests {
@Testvoid contextLoads() {MyThread t = new MyThread();// 啟動線程//t.run(); // 不會啟動線程,不會分配新的分支棧。(這種方式就是單線程。)t.start();// 這里的代碼還是運行在主線程中。for (int i = 0; i < 1000; i++) {System.out.println("主線程--->" + i);}}
}
class MyThread extends Thread{@Overridepublic void run() {for (int i = 0; i < 1000; i++) {System.out.println("分支線程 = " + i);}}
}

注意

  • t.run() 不會啟動線程,只是普通的調用方法而已。不會分配新的分支棧。(這種方式就是單線程。)
  • t.start() 方法的作用是:啟動一個分支線程,在JVM中開辟一個新的棧空間,這段代碼任務完成之后,瞬間就結束了。
    這段代碼的任務只是為了開啟一個新的棧空間,只要新的棧空間開出來,start()方法就結束了。線程就啟動成功了。
    啟動成功的線程會自動調用run方法,并且run方法在分支棧的棧底部(壓棧)。
    run方法在分支棧的棧底部,main方法在主棧的棧底部。run和main是平級的。

調用run()方法內存圖:

在這里插入圖片描述

調用start()方法內存圖:

在這里插入圖片描述

第二種方式:

編寫一個類,實現 java.lang.Runnable 接口,實現run方法。

  • 怎么創建線程對象? new線程類傳入可運行的類/接口。
  • 怎么啟動線程呢? 調用線程對象的 start() 方法。

偽代碼:

// 定義一個可運行的類
public class MyRunnable implements Runnable {public void run(){}
}
// 創建線程對象
Thread t = new Thread(new MyRunnable());
// 啟動線程
t.start();

eg

public class ThreadTest03 {public static void main(String[] args) {Thread t = new Thread(new MyThread());t.start();for (int i = 0; i < 100; i++) {System.out.println("主線程--->" + i);}}
}
public class MyRunnable implements Runnable {public void run() {for (int i = 0; i < 100; i++) {System.out.println("分支線程 = " + i);}}
}

采用匿名內部類創建:

public class ThreadTest04 {public static void main(String[] args) {// 創建線程對象,采用匿名內部類方式。Thread t = new Thread(new Runnable() {public void run() {for (int i = 0; i < 100; i++) {System.out.println("t線程---> " + i);}}});// 啟動線程t.start();for (int i = 0; i < 100; i++) {System.out.println("main線程---> " + i);}}
}

注意:
第二種方式實現接口比較常用,因為一個類實現了接口,它還可以去繼承其它的類,更靈活。

7、獲取當前線程對象、獲取線程對象名字、修改線程對象名字

方法名作用
static Thread currentThread()獲取當前線程對象
String getName()獲取線程對象名字
void setName(String name)修改線程對象名字

當線程沒有設置名字的時候,默認的名字是什么?

  • Thread-0
  • Thread-1
  • Thread-2
  • Thread-3

eg

public class MyThread2 extends Thread {@Overridepublic void run() {for (int i = 0; i < 100; i++) {// currentThread就是當前線程對象。當前線程是誰呢?// 當t1線程執行run方法,那么這個當前線程就是t1// 當t2線程執行run方法,那么這個當前線程就是t2Thread currentThread = Thread.currentThread();System.out.println(currentThread.getName() + "-->" + i);//System.out.println(super.getName() + "-->" + i);//System.out.println(this.getName() + "-->" + i);}}
}

8、關于線程的sleep方法

方法名作用
static void sleep(long millis)讓當前線程休眠millis秒
  1. 靜態方法:Thread.sleep(1000);
  2. 參數是毫秒
  3. 作用: 讓當前線程進入休眠,進入“阻塞狀態”,放棄占有CPU時間片,讓給其它線程使用。
    這行代碼出現在A線程中,A線程就會進入休眠。
    這行代碼出現在B線程中,B線程就會進入休眠。
  4. Thread.sleep()方法,可以做到這種效果:間隔特定的時間,去執行一段特定的代碼,每隔多久執行一次。

eg

public class ThreadTest05 {public static void main(String[] args) {//每打印一個數字睡1sfor (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName() + "--->" + i);// 睡眠一秒try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}

9、關于線程中斷sleep()的方法

方法名作用
void interrupt()終止線程的睡眠

eg

public class ThreadTest06 {public static void main(String[] args) {Thread t = new Thread(new MyRunnable2());t.setName("t");t.start();// 希望5秒之后,t線程醒來(5秒之后主線程手里的活兒干完了。)try {Thread.sleep(100*5);} catch (InterruptedException e) {e.printStackTrace();}// 終斷t線程的睡眠(這種終斷睡眠的方式依靠了java的異常處理機制。)t.interrupt();}
}
class MyRunnable2 implements Runnable{public void run() {System.out.println(Thread.currentThread().getName() + "---> begin");// 睡眠1年try {Thread.sleep(1000 * 60 * 60 * 24 * 365);} catch (InterruptedException e

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

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

相關文章

uniapp實現列表拖拽排序+滑動刪除功能

此篇代碼在原插件基礎進行了bug修改與滑動功能的新增 原插件地址 HM-dragSorts.vue組件使用 HM-dragSorts.vue <template><view class""><view class"HM-drag-sort" :style"{height: ListHeightrpx,background-color: listBackground…

魔法方法介紹

【一】什么是魔法方法 在類內部達到指定條件會自動觸發的方法 【二】魔法方法 # 【1】__init__ &#xff1a; 實例化類得到對象的時候會自動觸發 class Student(object):def __init__(self):print(f"實例化類的時候觸發") # 實例化類的時候觸發 ? s Student…

在云服務器上運行StyleGAN3生成偽樣本

首先是傳入數據&#xff0c;這里我們不做贅述。 對于數據格式的裁剪&#xff0c;可以通過以下代碼進行&#xff1a; from glob import glob from PIL import Image import os from tqdm import tqdm from tqdm.std import trangeimg_path glob(r"C:\Users\Administrato…

【Oracle篇】rman物理備份工具的基礎理論概述(第一篇,總共八篇)

??博主介紹??&#xff1a; ?又是一天沒白過&#xff0c;我是奈斯&#xff0c;DBA一名? ???擅長Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式數據倉庫)、Linux&#xff0c;也在擴展大數據方向的知識面??? ??????大佬們都喜歡靜靜的看文章&am…

嵌入式是大坑的說法,是否與學生的信息不對稱有關?

在開始前我有一些資料&#xff0c;是我根據網友給的問題精心整理了一份「嵌入式的資料從專業入門到高級教程」&#xff0c; 點個關注在評論區回復“888”之后私信回復“888”&#xff0c;全部無償共享給大家&#xff01;&#xff01;&#xff01; 目前也算是在搞嵌入式&#…

【深度學習】時空圖卷積網絡(STGCN),預測交通流量

論文地址&#xff1a;https://arxiv.org/abs/1709.04875 Spatio-Temporal Graph Convolutional Networks: A Deep Learning Framework for Traffic Forecasting 文章目錄 一、摘要二、數據集介紹美國洛杉磯交通數據集 METR-LA 介紹美國加利福尼亞交通數據集 PEMS-BAY 介紹美國…

Cocktail for Mac 激活版:一站式系統優化與管理神器

Cocktail for Mac是一款專為Mac用戶打造的系統優化與管理工具&#xff0c;憑借其強大的功能和簡便的操作&#xff0c;贏得了廣大用戶的喜愛。這款軟件集系統清理、修復和優化于一身&#xff0c;能夠幫助用戶輕松解決Mac系統中的各種問題&#xff0c;提高系統性能。 Cocktail fo…

Leetcode-有效的括號(帶圖)

20. 有效的括號 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/valid-parentheses/ 題目 給定一個只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判斷字符串是否有效。 有效字符串需滿足&…

在做題中學習(59):除自身以為數組的乘積

238. 除自身以外數組的乘積 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a;前綴積和后綴積 思路&#xff1a;answer中的每一個元素都是除自己以外所有元素的和。那就處理一個前綴積數組和后綴積數組。 而前綴積(f[i])是&#xff1a;[0,i-1]所有元素的乘積 后綴…

如何利用香港多IP服務器實現定制化的網絡服務

如何利用香港多IP服務器實現定制化的網絡服務 在當今數字化快速發展的時代&#xff0c;企業對于網絡服務的需求日益增加&#xff0c;尤其是對于定制化和高度可調整的網絡服務的需求。香港&#xff0c;作為國際金融中心和數據中心的樞紐&#xff0c;提供了優越的網絡基礎設施和…

什么是蜜罐,在當前網絡安全形勢下,蜜罐能提供哪些幫助

在當前的互聯網時代&#xff0c;網絡安全威脅日益嚴峻&#xff0c;攻擊手段層出不窮。為了應對這些威脅&#xff0c;網絡安全專家們不斷探索新的防御手段&#xff0c;在過去的幾年里&#xff0c;一種更加積極主動的網絡安全方法正在興起。蜜罐技術便是這樣一種備受矚目的主動防…

【教學類-55-05】20240516圖層順序挑戰(三格長條紙加黑色邊框、3*3、5張,不重復7186張,9坐標點顏色哈希值去重、保留5色)

背景需求&#xff1a; 前期測試了4*4框格種的8種顏色&#xff0c;隨機抽取7種&#xff0c;隨機排列圖層&#xff0c;去掉相同的圖片、保留7種顏色的圖片&#xff0c;最后獲得5400張樣圖 【教學類-55-04】20240515圖層順序挑戰&#xff08;四格長條紙加黑色邊框、4*4、7張&…

Python程序設計 文件處理(二)

實驗十二 文件處理 第1關&#xff1a;讀取宋詞文件&#xff0c;根據詞人建立多個文件 讀取wjcl/src/step1/宋詞.txt文件&#xff0c; 注意&#xff1a;宋詞文件的標題行的詞牌和作者之間是全角空格&#xff08;" ")可復制該空格 在wjcl/src/step3/cr文件夾下根據每…

【CSND博客紀念】“創作紀念日:從靈感迸發到小有成就——我的CSND博客創作之旅”

&#x1f3a9; 歡迎來到技術探索的奇幻世界&#x1f468;?&#x1f4bb; &#x1f4dc; 個人主頁&#xff1a;一倫明悅-CSDN博客 ?&#x1f3fb; 作者簡介&#xff1a; C軟件開發、Python機器學習愛好者 &#x1f5e3;? 互動與支持&#xff1a;&#x1f4ac;評論 &…

記錄下git的基本操作

初始化git git init git clone 拉取各分支的最新代碼 git fetch 切換分支 git checkout 分支名 提交相關操作 git add . git commit -m “提交備注” 兩個一起 git commit -am “提交備注” 如果需要撤銷操作 git log 查詢日志,提交id git revert git revert HEAD 撤銷前一…

算法分析與設計復習__遞歸方程與分治

總結自&#xff1a;【算法設計與分析】期末考試突擊課_嗶哩嗶哩_bilibili 1.遞歸&#xff0c;遞歸方程 1.1遞歸條件: 1.一個問題的解可以分解為幾個子問題的解&#xff1b; 2.這個問題與分解之后的子問題&#xff0c;除了數據規模不同&#xff0c;求解思路完全一樣; 3.存在…

【面試干貨】一個數組的倒序

【面試干貨】一個數組的倒序 1、實現思想2、代碼實現 &#x1f496;The Begin&#x1f496;點點關注&#xff0c;收藏不迷路&#x1f496; 1、實現思想 創建一個新的數組&#xff0c;然后將原數組的元素按相反的順序復制到新數組中。 2、代碼實現 package csdn;public class…

高效微砂沉淀澄清設備工藝流程

諸城市鑫淼環保小編帶大家了解一下高效微砂沉淀澄清設備工藝流程 微砂循環重介速沉設備 微砂高速絮凝沉淀系統巧妙地將混凝、絮凝、沉淀、分離幾個過程優化組合到一個設備中&#xff0c;并引入“微砂”&#xff0c;提升了水中懸浮固體的絮凝效率和分離效率&#xff0c;同時&…

如何幫孩子學好編程

學習編程對于孩子來說是一項非常有益的技能&#xff0c;不僅可以培養孩子的邏輯思維能力&#xff0c;還可以提高孩子的問題解決能力和創造力。以下是一些建議&#xff0c;幫助孩子學好編程&#xff1a; 選擇適合孩子的編程語言和工具&#xff1a;根據孩子的年齡和興趣選擇合適的…