日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

线程基础知识_线程生命周期_从JVM内存结构看多线程下的共享资源

發(fā)布時(shí)間:2024/7/5 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线程基础知识_线程生命周期_从JVM内存结构看多线程下的共享资源 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

線程生命周期

線程狀態(tài)

New: 線程創(chuàng)建(new Thread()) Runnable: 線程可運(yùn)行(thread.start()), 注: 調(diào)用start并不一定是運(yùn)行狀態(tài), 可能在等待CPU調(diào)度 Running: 線程進(jìn)入運(yùn)行狀態(tài) Blocked: 阻塞狀態(tài)(object.wait, Thread.sleep) Terminal: 死亡狀態(tài)(線程正常/非正常結(jié)束運(yùn)行)

thread.start()方法分析線程狀態(tài)

start源碼:

public synchronized void start() {//使用if判斷thread狀態(tài), threadStatus為0表示當(dāng)前線程處于new狀態(tài)if (threadStatus != 0)throw new IllegalThreadStateException();//將線程添加到對(duì)應(yīng)線程組中group.add(this);boolean started = false;try {//native方法start0();started = true;} finally {try {//根據(jù)線程是否啟動(dòng)成功, 來(lái)決定是否添加threadStartFailed中if (!started) {group.threadStartFailed(this);}} catch (Throwable ignore) {}}}

Thread使用threadStatus判斷線程狀態(tài), 當(dāng)線程啟動(dòng)后, 再次啟動(dòng), 或者線程處于死亡狀態(tài), 還對(duì)線程進(jìn)行start, 就會(huì)因?yàn)閠hreadStatus拋出IllegalThreadStateException

Thread中的模板設(shè)計(jì)模式

模板設(shè)計(jì)模式: 接口定義算法骨架, 在不同的子類中, 對(duì)其算法骨架具有不同的實(shí)現(xiàn)方式
由于Thread實(shí)現(xiàn)了Runnable接口, 在Runnable中定義了算法骨架(run方法的定義), 因此創(chuàng)建線程一般都是重新run方法(繼承Thread, 或者實(shí)現(xiàn)Runnable)
Thread中的run方法:

@Overridepublic void run() {//target代表new Thread(Runnable target)中傳入的Runnable對(duì)象if (target != null) {target.run();}}

從上面的run方法得出, 創(chuàng)建線程的2中常用方式:

1. new Thread(){@Overridepublic void run() {//.........}}; 2.new Thread(new Runnable() {@Overridepublic void run() {//.......}});

二者的區(qū)別:
方式1中, 不能做到run方法重用, 方式2中, 可以做到run方法重用(一個(gè)runnable對(duì)象能給多個(gè)thread使用)
這里一定要注意共享資源的使用, 這里很容易讓人誤解: 多個(gè)線程共享一個(gè)資源的時(shí)候, 必須保證這樣的資源只有一份, 解決方式有: 當(dāng)多個(gè)runnable對(duì)象時(shí), 多個(gè)thread, 可以設(shè)置共享變量是static類型, 當(dāng)只存在一份runnbable對(duì)象, 可以設(shè)置共享變量是普通成員變量, 其實(shí)這兩種方式都是類似的, 只是取決于使用哪種方式創(chuàng)建線程, 使用多個(gè)Runnable對(duì)象, 還是一個(gè)Runnable對(duì)象.

Thread的init

調(diào)用線程的構(gòu)造方法的時(shí)候, 就會(huì)自動(dòng)調(diào)用Thread的init方法

public Thread() {init(null, null, "Thread-" + nextThreadNum(), 0);}//線程初始化操作//stackSize: 設(shè)置線程內(nèi)遞歸深度private void init(ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc,boolean inheritThreadLocals) {//此時(shí)獲取的線程是main線程, main線程執(zhí)行子線程的初始化操作, 只有當(dāng)子線程//執(zhí)行run操作的時(shí)候, 才意味著子線程啟動(dòng)Thread parent = currentThread();SecurityManager security = System.getSecurityManager();//設(shè)置當(dāng)當(dāng)前線程的groupif (g == null) {if (security != null) {g = security.getThreadGroup();}if (g == null) {g = parent.getThreadGroup();}}g.checkAccess();if (security != null) {if (isCCLOverridden(getClass())) {security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);}}g.addUnstarted();//根據(jù)父線程屬性, 設(shè)置當(dāng)前線程的狀態(tài)this.group = g;this.daemon = parent.isDaemon();this.priority = parent.getPriority();if (security == null || isCCLOverridden(parent.getClass()))this.contextClassLoader = parent.getContextClassLoader();elsethis.contextClassLoader = parent.contextClassLoader;this.inheritedAccessControlContext =acc != null ? acc : AccessController.getContext();this.target = target;setPriority(priority);if (inheritThreadLocals && parent.inheritableThreadLocals != null)this.inheritableThreadLocals =ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);this.stackSize = stackSize;tid = nextThreadID();}

從init可以看出
當(dāng)線程創(chuàng)建的時(shí)候, 如果不指定group, priority等屬性的時(shí)候, 默認(rèn)使用父線程(例如: main線程創(chuàng)建一個(gè)新的線程)的值
一個(gè)線程的創(chuàng)建, 依賴與另外一個(gè)線程(注: main線程的創(chuàng)建依賴于JVM)
當(dāng)創(chuàng)建線程的時(shí)候, 沒(méi)有指定線程的Group, 默認(rèn)使用父線程所在的Group

ThreadGroup測(cè)試

思考引發(fā): 能否使用ThreadGroup進(jìn)行線程通信

/*** 測(cè)試ThreadGroup* @author regotto*/ public class ThreadGroupTest1 {public static void main(String[] args) {ThreadGroup group = new ThreadGroup("g1");System.out.println(group.getParent().getName());new Thread(group, "t1"){@Overridepublic void run(){//當(dāng)前線程組可以對(duì)父類線程組或父類線程組中線程進(jìn)行只讀操作, 寫操作將會(huì)出現(xiàn)異常System.out.println(Thread.currentThread().getThreadGroup().getParent().getName());}}.start();try {Thread.sleep(2_000);} catch (InterruptedException e) {e.printStackTrace();}//當(dāng)線程組內(nèi)線程(不是守護(hù)線程)都沒(méi)有存活, 線程組不會(huì)destroy, 需要主動(dòng)destroySystem.out.println("group.isDestroyed()" + group.isDestroyed());group.destroy();System.out.println("group.isDestroyed()" + group.isDestroyed());//將中斷group中所有線程 // group.interrupt();//將group中線程copy到線程數(shù)組中 // group.enumerate(new Thread[10]);} }

結(jié)論:
可以使用ThreadGroup進(jìn)行線程通信, 但是這種通信存在局限性, 可以使用ChildThreadGroup獲取ParentThreadGroup信息, 但是反過(guò)來(lái)就不行, 并且Child只能讀取Parent的信息, 不能進(jìn)行寫操作

守護(hù)線程

用通俗的話來(lái)描述, 守護(hù)線程就是后臺(tái)線程, 處理后臺(tái)任務(wù), 當(dāng)前臺(tái)任務(wù)執(zhí)行完, 守護(hù)線程自動(dòng)銷毀, 例如JVM就是守護(hù)線程
守護(hù)線程一般用于垃圾清理, 監(jiān)控

/*** 測(cè)試Daemon線程* 結(jié)論: 只有當(dāng)JVM中所有線程結(jié)束,Daemon才會(huì)結(jié)束, 即使線程組不同* @author regotto*/ public class DaemonThreadTest {public static void main(String[] args) {Thread T = new Thread(new ThreadGroup("group1"), () -> {Thread t1 = new Thread(() -> {System.out.println(Thread.currentThread().getThreadGroup() + "心跳線程開始");while (Thread.currentThread().isAlive()) {System.out.println(Thread.currentThread().getThreadGroup() + "心跳線程存活");}});t1.setDaemon(true);t1.start();System.out.println(Thread.currentThread().getThreadGroup() + "I/O操作線程");try {TimeUnit.MILLISECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getThreadGroup() + "I/O線程結(jié)束");}).start();try {TimeUnit.MILLISECONDS.sleep(4);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getThreadGroup() + "main thread dead");} }

T線程啟動(dòng), 啟動(dòng)一個(gè)守護(hù)線程t1開始心跳, 當(dāng)T線程死亡, 守護(hù)線程自動(dòng)退出心跳結(jié)束

ThreadHook

ThreadHook: 線程鉤子, 功能類似于守護(hù)線程(守護(hù)線程在前臺(tái)線程運(yùn)行中, 也都一直運(yùn)行, 但是線程鉤子只有最后程序結(jié)束,時(shí) 才執(zhí)行thread.start操作), 當(dāng)程序退出時(shí), 負(fù)責(zé)垃圾清理或執(zhí)行最后處理工作
ThreadHook測(cè)試

/*** Hook在接收到程序退出信號(hào)的時(shí)候才會(huì)退出, 當(dāng)直接kill進(jìn)程且等級(jí)為10, Hook不會(huì)執(zhí)行* Hook可以負(fù)責(zé)資源釋放操作(一定不要在Hook中執(zhí)行很耗時(shí)的操作, 會(huì)導(dǎo)致程序不能退出)* @author regotto*/ public class ThreadHook {public static void main(String[] args) {//Hook可以注冊(cè)多個(gè), 在JVM進(jìn)程將要退出, 執(zhí)行Hook中線程(多個(gè)Hook, 則并行執(zhí)行)Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Hook1 running")));Runtime.getRuntime().addShutdownHook(new Thread(){@Overridepublic void run() {System.out.println("Hook2 running");}}); } }

從JVM內(nèi)存結(jié)構(gòu)看多線程下的共享資源

各個(gè)模塊的簡(jiǎn)單描述

1.方法區(qū): 存放.class文件, 類信息, 常量, 靜態(tài)變量 2.程序計(jì)數(shù)器: 當(dāng).class文件加載JVM的方法區(qū)中時(shí), 當(dāng)前線程利用程序計(jì)數(shù)器執(zhí)行方法區(qū)中的字節(jié)碼指令由于不同的線程執(zhí)行指令不能相互影響, 因此設(shè)置程序計(jì)數(shù)器為線程私有 3.Java虛擬機(jī)棧: Java虛擬機(jī)棧是一個(gè)棧結(jié)構(gòu), 存放棧幀, 每一個(gè)棧幀就是一次方法調(diào)用(棧幀中存放方法局部變量表, 操作棧, 動(dòng)態(tài)鏈接, 方法出口等), 不同線程執(zhí)行過(guò)程調(diào)用的方法順序不同, 因此Java虛擬機(jī)棧就是線程私有的每一個(gè)線程的Java虛擬機(jī)棧生命期與線程相同 4.本地方法棧: 與Java虛擬機(jī)棧類似, 只是本地方法棧存放線程調(diào)用native方法的棧幀情況 5.堆內(nèi)存: 存放公共資源, JVM運(yùn)行過(guò)程中存放所有生成的對(duì)象, 被所有線程共享 7.直接內(nèi)存: 此塊區(qū)域歸屬于native方法(C/C++)執(zhí)行時(shí)用的堆空間

注: 由于Java虛擬機(jī)棧屬于線程私有, 當(dāng)每個(gè)線程的Java虛擬機(jī)空間越大, 那么能創(chuàng)建的線程就越少

總結(jié)

以上是生活随笔為你收集整理的线程基础知识_线程生命周期_从JVM内存结构看多线程下的共享资源的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久精品区 | 久草热在线观看 | 在线观看少妇 | 少妇高潮灌满白浆毛片免费看 | 中文字字幕第183页 欧美特级一级片 | 奇米影视9999 | 波多野结衣久久精品 | 可以免费观看的av网站 | 中文字幕一区二区三区手机版 | 国产 丝袜 欧美中文 另类 | 成人欧美一区二区三区黑人免费 | 奇米影视888| 丰满少妇一区二区三区视频 | 夜夜春夜夜爽 | 一级毛片黄片 | 夜夜嗨aⅴ一区二区三区 | 中文字幕第页 | 精品成人免费一区二区在线播放 | 五月婷婷网站 | 福利二区三区 | 69sex久久精品国产麻豆 | 绿帽在线| 日本老师巨大bbw丰满 | 国产明星换脸xxxx色视频 | 日韩欧美卡一卡二 | 九九在线观看高清免费 | 波多野吉衣久久 | 神宫寺奈绪一区二区三区 | 偷偷操不一样的久久 | 久操久操久操 | av在线影音 | 激情视频激情小说 | 青青国产在线观看 | 精品一区二区三区久久 | 亚洲人成免费电影 | 五月婷婷中文 | 在线看91 | 久久久www免费人成人片 | 亚洲29p | 波多野结衣女同 | 精品久久免费观看 | 日日摸日日碰夜夜爽无码 | 国产精品久久久免费观看 | 都市激情综合 | 日本大尺度床戏揉捏胸 | 欧美4区| 天堂中文在线播放 | 婷婷久| 亚洲国产精品无码久久久 | 国产日本欧美一区二区 | 蜜桃网站 | 丰满人妻一区二区三区53 | 亚洲骚片 | 欧美国产视频 | 日韩色图在线观看 | 第一页在线视频 | 朝鲜黄色片 | 免费视频福利 | 丁香婷婷社区 | 亚洲欧美日韩一区二区 | 国产网站无遮挡 | 色噜噜狠狠一区二区 | 中文字幕永久在线播放 | 国产精品久久久久久中文字 | 草逼国产 | 国产又粗又猛又爽又黄的网站 | 秋霞成人av | 99在线精品视频免费观看软件 | 小辣椒福利视频导航 | 欧美午夜性春猛交 | 91高跟黑色丝袜呻吟动态图 | 男人的天堂久久久 | 免费成人深夜小野草 | 青青草成人免费在线视频 | 动漫精品一区一码二码三码四码 | 美女被男生免费视频 | 欧美日韩一区在线 | 少妇4p| 台湾男男gay做爽爽的视频 | 国产精品美女久久久久 | 久久精品一区二区三区不卡牛牛 | 又爽又黄视频 | 色哟哟视频 | 性欧美free| 国产91绿帽单男绿奴 | 欧美日韩在线观看一区二区三区 | 91网在线观看 | 中文字幕在线一区 | 麻豆久久久9性大片 | 免费精品视频 | 人人超碰97 | 久草加勒比 | 日本美女视频一区 | 婷婷色在线 | 日韩一区二区免费播放 | 亚洲成人精品一区 | 久久国产露脸精品国产 | 中文字幕乱码人妻无码久久 | 亚洲精品乱码久久久久久蜜桃欧美 |