java線程

[TOC]

4 運(yùn)行原理

4.1 棧與棧幀

Java Virtual Machine Stacks (Java 虛擬機(jī)棧)
我們都知道 JVM 中由堆、棧、方法區(qū)所組成坤邪,其中棧內(nèi)存是給誰用的呢?其實(shí)就是線程,每個(gè)線程啟動(dòng)后萨醒,虛擬機(jī)就會(huì)為其分配一塊棧內(nèi)存。

  1. 每個(gè)棧由多個(gè)棧幀(Frame)組成苇倡,對(duì)應(yīng)著每次方法調(diào)用時(shí)所占用的內(nèi)存
  2. 每個(gè)線程只能有一個(gè)活動(dòng)棧幀富纸,對(duì)應(yīng)著當(dāng)前正在執(zhí)行的那個(gè)方法
image-20210126225409535

比如說囤踩,這里就有多個(gè)方法調(diào)用時(shí)的棧幀,每一個(gè)棧幀的右邊都有其自己對(duì)應(yīng)的變量和屬性晓褪。如果一個(gè)方法執(zhí)行完了堵漱,那么這個(gè)棧幀的內(nèi)存就會(huì)被回收,這個(gè)是不需要我們自己手動(dòng)操作的涣仿。

PS:我們調(diào)試的時(shí)候有一個(gè)小技巧勤庐,就是drop to frame,對(duì)應(yīng)圖片中的圖標(biāo)好港,他的意思是埃元,當(dāng)你點(diǎn)擊這個(gè)圖標(biāo),他會(huì)放棄當(dāng)前棧幀媚狰,并且返回上一個(gè)調(diào)用方法岛杀。

image-20210126225902191
image-20210126225840852

4.2 圖解運(yùn)行棧幀

java代碼

public class FrameTest {
    public static void main(String[] args) {
        method1(10);
    }

    private static void method1(int x) {
        int y = x + 1;
        Object m = method2();
        System.out.println(m);
    }

    private static Object method2() {
        Object n = new Object();
        return n;
    }
}   
  1. 首先一開始程序會(huì)程序棧、方法區(qū)和堆崭孤,方法區(qū)存儲(chǔ)的就是方法的內(nèi)容类嗤,main程序運(yùn)行的時(shí)候會(huì)有String數(shù)組,然后傳到main的局部變量表里面
image-20210126232953253
  1. main方法執(zhí)行第一行method1(10)代碼辨宠,這個(gè)代碼指令會(huì)放到程序計(jì)數(shù)器里面(程序計(jì)數(shù)器記錄的就是當(dāng)前線程需要執(zhí)行的指令遗锣,如果CPU要執(zhí)行這個(gè)線程,其實(shí)就是從程序計(jì)數(shù)器里面拿執(zhí)行的指令)
image-20210126233402654
  1. 當(dāng)執(zhí)行到了method1就會(huì)在程序棧里面開辟一個(gè)新的程序棧幀

    image-20210126233900325
  2. 當(dāng)執(zhí)行到Object m = method2()嗤形,這時(shí)又會(huì)開一個(gè)新的程序棧幀

    image-20210126234358464
  3. 當(dāng)執(zhí)行完了Object n =new Object()精偿,method2返回時(shí),method2的棧幀會(huì)被釋放了赋兵,同時(shí)method2棧幀里面的返回地址回到上一個(gè)方法笔咽,同時(shí)把m指向開辟的Object的堆內(nèi)存。

    image-20210126234635765
  4. 當(dāng)執(zhí)行完method1和main方法也是類似霹期。

4.3 多線程棧和棧幀

package com.bruce.test;

public class FrameTest {
    public static void main(String[] args) {
        Thread t1 = new Thread("t1") {
            @Override
            public void run() {
                method2();
            }
        };
        t1.start();
        method1(30);
    }

    private static void method1(int x) {
        int y = x + 1;
        Object m = method2();
        System.out.println(m);
    }

    private static Object method2() {
        Object n = new Object();
        return n;
    }
}

我們直接看這個(gè)的運(yùn)行情況叶组,就可以看到有兩個(gè)線程是已經(jīng)停止了

image-20210128223710073

可見,棧幀是以線程為單位历造,兩者相互獨(dú)立甩十,里面的變量是相互獨(dú)立的。

4.4 上下文切換

因?yàn)橐韵乱恍┰驅(qū)е翪PU不在執(zhí)行當(dāng)前的線程吭产,轉(zhuǎn)而執(zhí)行另一個(gè)線程的代碼:

  • 線程的CPU時(shí)間片用完
  • 垃圾回收
  • 有更高優(yōu)先級(jí)的線程需要運(yùn)行
  • 線程自己調(diào)用了sleep,yield,wait,join,park,synchronized,lock等方法

當(dāng)Context Switch發(fā)生時(shí)侣监,需要由操作系統(tǒng)保存當(dāng)前線程的狀態(tài),并恢復(fù)另一個(gè)線程的狀態(tài)臣淤,Java中對(duì)應(yīng)的概念就是程序計(jì)數(shù)器(Program counter Register)橄霉,它的作用就是記住下一條jvm指令的執(zhí)行地址,是線程私有的

  • 狀態(tài)包括程序計(jì)數(shù)器荒典、虛擬機(jī)棧中的每個(gè)棧幀的信息酪劫,如局部變量吞鸭、操作數(shù)棧、返回地址等
  • Context Switch頻繁發(fā)生會(huì)影響性能

4.4.1 圖解上下文切換

image-20210128230204016
  1. 比如說由main線程切換到t1線程的時(shí)候覆糟,main線程里面的狀態(tài)信息都會(huì)保存起來
  2. CPU會(huì)執(zhí)行t1線程里面的程序計(jì)數(shù)器里面的指令刻剥。

5 線程的常用方法

方法名 static 功能說明 注意
start 啟動(dòng)一個(gè)新線程,在新的線程運(yùn)行run方法中的代碼 start方法只是讓線程進(jìn)入就緒滩字,里面代碼不一定立刻運(yùn)行(CPU的時(shí)間片還沒分給它)造虏。每個(gè)線程對(duì)象的start方法智能調(diào)用一次,如果調(diào)用了多次會(huì)出現(xiàn)IllegalThreadStateException
run 新線程啟動(dòng)后悔調(diào)用的方法 如果在構(gòu)造Thread對(duì)象時(shí)傳遞了Runnable參數(shù)麦箍,則線程啟動(dòng)后悔調(diào)用Runnable中的run方法漓藕,否則默認(rèn)不執(zhí)行任何操作。但可以創(chuàng)建Thread的子類對(duì)象來覆蓋默認(rèn)行為
join 等待線程運(yùn)行結(jié)束
join(long n) 等待線程運(yùn)行結(jié)束挟裂,最多等待n毫秒
get() 獲取線程長整形的id id唯一
getName() 獲取線程名
setName(String) 修改線程名
getPriority() 獲取線程優(yōu)先級(jí)
setPriority(int) 修改線程優(yōu)先級(jí) java中規(guī)定線程優(yōu)先級(jí)1~10的整數(shù)享钞,較大優(yōu)先級(jí)能提高該線程被CPU調(diào)度的概率
getState(0) 獲取線程狀態(tài) Java中線程狀態(tài)是用6個(gè)enum表示,分別為NEW RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED
isInterrupted() 判斷是否被打斷 不會(huì)清除打斷標(biāo)記
isAlive() 線程存活(還沒有運(yùn)行完畢)
interrupt() 打斷線程 如果被打斷線程正在sleep,wait,join會(huì)導(dǎo)致被打斷的線程拋出InterruptedException,并清除打斷標(biāo)記诀蓉;如果打斷的正在運(yùn)行的線程栗竖,則會(huì)設(shè)置打斷標(biāo)記;park的線程被打斷渠啤,也會(huì)設(shè)置打斷標(biāo)記
interrupted() static 判斷當(dāng)前線程是否被打斷 會(huì)清除打斷標(biāo)記
currentThread(0) static 獲取點(diǎn)前正在執(zhí)行的線程
sleep(long n) static 讓當(dāng)前執(zhí)行的線程休眠n毫秒狐肢,休眠時(shí)讓出cpu的時(shí)間片給其他線程
yield() static 提示線程調(diào)度器讓出當(dāng)前線程對(duì)CPU的使用 主要是為了測試和調(diào)試

二段終止模式

流程圖

image-20210125224038357
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市沥曹,隨后出現(xiàn)的幾起案子份名,更是在濱河造成了極大的恐慌,老刑警劉巖妓美,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件僵腺,死亡現(xiàn)場離奇詭異,居然都是意外死亡部脚,警方通過查閱死者的電腦和手機(jī)想邦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門裤纹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來委刘,“玉大人,你說我怎么就攤上這事鹰椒∥疲” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵漆际,是天一觀的道長淆珊。 經(jīng)常有香客問我,道長奸汇,這世上最難降的妖魔是什么施符? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任往声,我火速辦了婚禮,結(jié)果婚禮上戳吝,老公的妹妹穿的比我還像新娘浩销。我一直安慰自己,他們只是感情好听哭,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布慢洋。 她就那樣靜靜地躺著,像睡著了一般陆盘。 火紅的嫁衣襯著肌膚如雪普筹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天隘马,我揣著相機(jī)與錄音太防,去河邊找鬼。 笑死酸员,一個(gè)胖子當(dāng)著我的面吹牛杏头,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播沸呐,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼醇王,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了崭添?” 一聲冷哼從身側(cè)響起寓娩,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎呼渣,沒想到半個(gè)月后棘伴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屁置,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年焊夸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓝角。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡阱穗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出使鹅,到底是詐尸還是另有隱情揪阶,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布患朱,位于F島的核電站鲁僚,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜冰沙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一侨艾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拓挥,春花似錦蒋畜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至愿棋,卻和暖如春科展,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背糠雨。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國打工才睹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人甘邀。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓琅攘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親松邪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子坞琴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • Java 多線程 學(xué)習(xí)筆記 一. 線程與進(jìn)程 進(jìn)程是一個(gè)應(yīng)用程序,線程是一個(gè)進(jìn)程中的執(zhí)行場景/執(zhí)行單元逗抑。一個(gè)進(jìn)程可...
    六比特派大錘閱讀 269評(píng)論 0 0
  • 前言:對(duì)于java多線程的資料數(shù)不勝數(shù)剧辐,我們這里只是在學(xué)習(xí)后簡單地總結(jié)一下并給出一些小例子,本文適合java初學(xué)者...
    LiuHJ閱讀 329評(píng)論 0 0
  • 進(jìn)程是指運(yùn)行中的應(yīng)用程序,每個(gè)進(jìn)程都有自己獨(dú)立的地址空間邮府; 線程是進(jìn)程中執(zhí)行運(yùn)算的最小單位荧关,一個(gè)進(jìn)程中可以有多個(gè)線...
    SuperFatso閱讀 126評(píng)論 0 2
  • 進(jìn)程:正在執(zhí)行的程序,是一個(gè)動(dòng)態(tài)的過程 線程:是進(jìn)程中用于控制程序執(zhí)行的控制單元(執(zhí)行路徑褂傀,執(zhí)行情景) 進(jìn)程中至少...
    寶塔山上的貓閱讀 437評(píng)論 0 1
  • 首先回顧一下進(jìn)程(Process)和線程(Thread)的區(qū)別: 進(jìn)程:每個(gè)進(jìn)程都有獨(dú)立的代碼和數(shù)據(jù)空間(進(jìn)程上下...
    DN_0915閱讀 266評(píng)論 0 1