日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

使用stop、suspend方法來中斷線程的壞處在哪?

Android編程精選 ? 來源:CSDN技術(shù)社區(qū) ? 作者:浪舟子 ? 2021-07-26 14:23 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

我們知道像stop、suspend這幾種中斷或者阻塞線程的方法在較高java版本中已經(jīng)被標(biāo)記上了@Deprecated過期標(biāo)簽,那么為什么她們?cè)?jīng)登上了java的歷史舞臺(tái)而又漸漸的推出了舞臺(tái)呢,到底是人性的扭曲還是道德的淪喪呢,亦或是她們不思進(jìn)取被取而代之呢,如果是被取而代之,那么取而代之的又是何方人也,本文我們將一探究竟。

一、stop的落幕首先stop方法的作用是什么呢,用java源碼中的一句注釋來了解一下:Forces the thread to stop executing.,即強(qiáng)制線程停止執(zhí)行,‘Forces’似乎已經(jīng)透漏出了stop方法的蠻狠無理。那么我們?cè)倏纯磈ava開發(fā)者是怎們解釋stop被淘汰了的。

我們從中可以看出以下幾點(diǎn):

stop這種方法本質(zhì)上是不安全的

使用Thread.stop停止線程會(huì)導(dǎo)致它解鎖所有已鎖定的監(jiān)視器,即直接釋放當(dāng)前線程已經(jīng)獲取到的所有鎖,使得當(dāng)前線程直接進(jìn)入阻塞狀態(tài)

我們舉例來看一下上邊提到的兩點(diǎn):

public static void main(String[] args) throws InterruptedException {

Object o1=new Object();

Object o2=new Object();

Thread t1=new Thread(()-》{

synchronized (o1)

{

synchronized (o2)

{

try {

System.out.println(“t1獲取到鎖”);

Thread.sleep(5000);

System.out.println(“t1結(jié)束”);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

});

t1.start();

Thread.sleep(1000);

Thread t2=new Thread(()-》{

synchronized (o1)

{

synchronized (o2)

{

try {

System.out.println(“t2獲取到鎖”);

Thread.sleep(5000);

System.out.println(“t2結(jié)束”);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

});

t2.start();

t1.stop();

}

運(yùn)行結(jié)果:

1fb0958c-e009-11eb-9e57-12bb97331649.png

可以看到,當(dāng)線程t1在獲取到o1和o2兩個(gè)鎖開始執(zhí)行,在還沒有執(zhí)行結(jié)束的時(shí)候,主線程調(diào)用了t1的stop方法中斷了t1的執(zhí)行,釋放了t1線程獲取到的所有鎖,中斷后t2獲取到了o1和o2鎖,開始執(zhí)行直到結(jié)束,而t1卻夭折在了sleep的時(shí)候,sleep后的代碼沒有執(zhí)行。

因此使用stop我們?cè)诓恢谰€程到底運(yùn)行到了什么地方,暴力的中斷了線程,如果sleep后的代碼是資源釋放、重要業(yè)務(wù)邏輯等比較重要的代碼的話,亦或是其他線程依賴t1線程的運(yùn)行結(jié)果,那直接中斷將可能造成很嚴(yán)重的后果。

那么不建議使用stop中斷線程我們應(yīng)該怎么去優(yōu)雅的結(jié)束一個(gè)線程呢,我們可以存java開發(fā)者的注釋中窺探到一種解決方案:

1fdbe836-e009-11eb-9e57-12bb97331649.png

可以看到j(luò)ava開發(fā)者推薦我們使用以下兩種方法來優(yōu)雅的停止線程:

1.定義一個(gè)變量,由目標(biāo)線程去不斷的檢查變量的狀態(tài),當(dāng)變量達(dá)到某個(gè)狀態(tài)時(shí)停止線程。

代碼舉例如下:

volatile static boolean flag=false;

public static void main(String[] args) throws InterruptedException {

Object o1=new Object();

Thread t1=new Thread(()-》{

synchronized (o1)

{

try {

System.out.println(“t1獲取到鎖”);

while (!flag)

Thread.sleep(5000);//執(zhí)行業(yè)務(wù)邏輯

System.out.println(“t1結(jié)束”);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

t1.start();

Thread.sleep(1000);

Thread t2=new Thread(()-》{

synchronized (o1)

{

try {

System.out.println(“t2獲取到鎖”);

Thread.sleep(5000);//執(zhí)行業(yè)務(wù)邏輯

System.out.println(“t2結(jié)束”);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

t2.start();

flag=true;

}

運(yùn)行結(jié)果:

1ffacdc8-e009-11eb-9e57-12bb97331649.png

2.使用interrupt方法中斷線程。

代碼舉例如下:

public static void main(String[] args) throws InterruptedException {

Object o1=new Object();

Thread t1=new Thread(()-》{

synchronized (o1)

{

System.out.println(“t1獲取到鎖”);

while (!Thread.currentThread().isInterrupted()) {

for (int i = 0; i 《 100; i++) {

if(i==50)

System.out.println();

System.out.print(i+“ ”);

}

System.out.println();

}

System.out.println(“t1結(jié)束”);

}

});

t1.start();

Thread t2=new Thread(()-》{

synchronized (o1)

{

try {

System.out.println(“t2獲取到鎖”);

Thread.sleep(5000);//執(zhí)行業(yè)務(wù)邏輯

System.out.println(“t2結(jié)束”);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

t2.start();

t1.interrupt();

}

運(yùn)行結(jié)果:

202dbdb4-e009-11eb-9e57-12bb97331649.png

我們用while (!Thread.currentThread().isInterrupted())來不斷判斷當(dāng)前線程是否被中斷,中斷的話則讓線程自然消亡并釋放鎖??梢钥吹秸{(diào)用interrupt方法后并不會(huì)像stop那樣暴力的中斷線程,會(huì)等到當(dāng)前運(yùn)行的邏輯結(jié)束后再檢查是否中斷,非常的優(yōu)雅。另外,關(guān)注Java知音公眾號(hào),回復(fù)“后端面試”,送你一份面試題寶典!

注:運(yùn)行舉例代碼可能不會(huì)打印出數(shù)字,這是因?yàn)閠1線程運(yùn)行到while(!Thread.currentThread().isInterrupted())時(shí),主線程已經(jīng)調(diào)了interrupt方法,因此多次運(yùn)行可能會(huì)打印出數(shù)字。

二、suspend的落幕suspend方法的作用是掛起某個(gè)線程直到調(diào)用resume方法來恢復(fù)該線程,但是調(diào)用了suspend方法后并不會(huì)釋放被掛起線程獲取到的鎖,正因如此就給suspend和resume這哥倆貼上了容易引發(fā)死鎖的標(biāo)簽,當(dāng)然這也正是導(dǎo)致suspend和resume退出歷史舞臺(tái)的罪魁禍?zhǔn)?。同樣我們看看java開發(fā)者為suspend的淘汰給出的理由:

206731fc-e009-11eb-9e57-12bb97331649.png

從中我們可以得出以下結(jié)論:

suspend具有天然的死鎖傾向

當(dāng)某個(gè)線程被suspend后,該線程持有的鎖不會(huì)被釋放,其他線程也就不能訪問這些資源

suspend某個(gè)線程后,如果在resume的過程中出現(xiàn)異常導(dǎo)致resume方法執(zhí)行失敗,則lock無法釋放,導(dǎo)致死鎖

接下來模擬一下由suspend引起的死鎖場(chǎng)景,Talk is cheap,show my code:

public static void main(String[] args) throws InterruptedException {

Object o1=new Object();

Object o2=new Object();

Thread t1=new Thread(()-》{

synchronized (o1)

{

System.out.println(“t1獲取到o1鎖開始執(zhí)行”);

try {

Thread.sleep(5000);//模擬執(zhí)行業(yè)務(wù)邏輯

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(“t1執(zhí)行結(jié)束”);

}

});

t1.start();

Thread t2=new Thread(()-》{

synchronized (o2)

{

System.out.println(“t2獲取到o2開始執(zhí)行”);

try {

Thread.sleep(2000);//執(zhí)行耗時(shí)業(yè)務(wù)

} catch (InterruptedException e) {

e.printStackTrace();

}

synchronized (o1)

{

System.out.println(“t2獲取到o1鎖開始繼續(xù)執(zhí)行”);

}

System.out.println(“t2執(zhí)行結(jié)束”);

}

});

t2.start();

Thread.sleep(1000);

t1.suspend();

//假設(shè)拋出了一個(gè)未知異常

int i=1/0;

t1.resume();

}

運(yùn)行結(jié)果:

20736242-e009-11eb-9e57-12bb97331649.png

可以看到,整個(gè)程序卡的死死的,在調(diào)用resume恢復(fù)t1線程之前拋出了一個(gè)未知異常,導(dǎo)致t1一直掛起進(jìn)而無法釋放o1鎖,而t2需要獲取到o1鎖后才能繼續(xù)執(zhí)行,但苦苦等待,奈何o1被t1拿捏的死死的,從此整個(gè)程序就陷入了無盡的等待中----死鎖。

作者丨浪舟子

blog.csdn.net/qq_40400960/article/details/112651249

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 中斷
    +關(guān)注

    關(guān)注

    5

    文章

    920

    瀏覽量

    43887

原文標(biāo)題:為什么強(qiáng)烈不推薦使用stop、suspend方法來中斷線程?

文章出處:【微信號(hào):AndroidPush,微信公眾號(hào):Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    一文看懂PCIe中斷機(jī)制

    PCIe 中斷機(jī)制主要分為兩類:一類是繼承自傳統(tǒng) PCI 的 物理中斷線(INTx)中斷,通過硬件引腳觸發(fā);另一類是 MSI(Message Signaled Interrupt)中斷
    的頭像 發(fā)表于 03-11 09:35 ?521次閱讀
    一文看懂PCIe<b class='flag-5'>中斷</b>機(jī)制

    解析Linux的進(jìn)程、線程和協(xié)程

    系統(tǒng)的穩(wěn)定性和安全性。 (3)創(chuàng)建與銷毀:Linux使用fork()系統(tǒng)調(diào)用來創(chuàng)建新進(jìn)程,通過exit()終止進(jìn)程。 線程(Thread) 線程是進(jìn)程內(nèi)的執(zhí)行單元,多個(gè)線程共享相
    發(fā)表于 12-22 11:00

    RISC-V怎么實(shí)現(xiàn)核間中斷?核心本地中斷控制器(CLINT)深度解析

    于每個(gè)核心 / 硬件線程(hart)的中斷控制器,專門處理「核心本地、非共享」的中斷類型,區(qū)別于處理外設(shè)共享中斷的 PLIC(Platform-Level Interrupt Cont
    的頭像 發(fā)表于 12-13 14:06 ?2696次閱讀
    RISC-V怎么實(shí)現(xiàn)核間<b class='flag-5'>中斷</b>?核心本地<b class='flag-5'>中斷</b>控制器(CLINT)深度解析

    線程的系統(tǒng)

    線程系統(tǒng)的事件響應(yīng)也是在中斷中完成的,但事件的處理是在線程中完成的。在多線程系統(tǒng)中,線程中斷
    發(fā)表于 12-08 07:55

    Linux多線程對(duì)比單線程的優(yōu)勢(shì)

    ,而單線程則需要通過進(jìn)程間通信實(shí)現(xiàn)?!干舷挛那袚Q開銷小」:線程的上下文切換比進(jìn)程小,因?yàn)樗鼈児蚕硐嗤牡刂房臻g?!柑岣唔憫?yīng)性」:多線程可以使程序更加響應(yīng)用戶輸入或其他事件,避免阻塞。
    發(fā)表于 12-01 06:11

    使用fal api 讀寫1024 字節(jié)數(shù)據(jù),需要需要考慮被高優(yōu)先級(jí)線程打斷嗎?

    使用fal api 讀寫1024 字節(jié)數(shù)據(jù),需要需要考慮被高優(yōu)先級(jí)線程打斷嗎?
    發(fā)表于 10-10 07:16

    切換線程中斷被屏蔽怎么解決?

    退出,已經(jīng)切換到main線程,但是發(fā)現(xiàn)此時(shí)中斷是被屏蔽的。 跟代碼發(fā)現(xiàn)rt_schedule最后切換線程時(shí)是先調(diào)用rt_hw_context_switch,再
    發(fā)表于 09-29 07:48

    ulog輸出異常-中斷線程打印沖突怎么解決?

    邏輯:can收到數(shù)據(jù)后,can中斷打印test,并把數(shù)據(jù)放到消息隊(duì)列,main函數(shù)的消息隊(duì)列打印消息內(nèi)容 問題:只要can中斷中有test打印的代碼,整個(gè)串口就會(huì)卡死; 中斷中無test打印的代碼
    發(fā)表于 09-28 11:44

    rt_sem_take卡住導(dǎo)致線程無法正常運(yùn)行怎么解決?

    串口接收數(shù)據(jù)后release信號(hào)量,接收線程take sem,高頻大數(shù)據(jù)量接受數(shù)據(jù),運(yùn)行一段時(shí)間后接受線程suspend,但是release正常釋放 出現(xiàn)問題問題后查看信息如下: 接受線程
    發(fā)表于 09-23 08:17

    中斷發(fā)送信號(hào)量不能釋放等待信號(hào)量的線程是怎么回事?

    MCU為stm32f407vgt6,rt-thread的版本為4.0.3。 代碼如下: /* 接收數(shù)據(jù)回調(diào)函數(shù),該函數(shù)會(huì)在uart中斷例程中調(diào)用*/ static rt_err_t
    發(fā)表于 09-10 06:28

    線程超時(shí)函數(shù)中 assert 失敗是什么原因?qū)е碌?

    最近調(diào)試 gd32h759 遇到了一個(gè)十分奇怪的問題,在初步調(diào)通所有的邏輯功能后,發(fā)現(xiàn)系統(tǒng)經(jīng)常會(huì)在運(yùn)行一段時(shí)間后死在一個(gè)奇怪的線程超時(shí)函數(shù)中 assert 失敗導(dǎo)致卡死。用 cmbacktrace
    發(fā)表于 09-09 06:56

    STM32L433VCT6進(jìn)入STOP模式2之后,功耗依然和正常運(yùn)行模式?jīng)]有差別,為什么?

    STM32CubeMX上配置power savinf mode 2、系統(tǒng)電源供電時(shí)LDO 結(jié)果: 1、運(yùn)行是10mA,進(jìn)入STOP模式時(shí)是9.9mA; 2、掛仿真,沒有任何喚醒的中斷產(chǎn)生,應(yīng)該是進(jìn)入STOP模式了。 請(qǐng)教壇子
    發(fā)表于 07-21 06:42

    想在rtsmart中使用uart2,是不是只能通過修改設(shè)備樹方法來實(shí)現(xiàn)uart2的復(fù)用呀?

    我想在rtsmart中使用uart2,是不是只能通過修改設(shè)備樹方法來實(shí)現(xiàn)uart2的復(fù)用呀? 修改設(shè)備樹后如何只編譯設(shè)備樹文件? 編譯生成的文件可以直接替換到廬山派里嗎,具體替換路徑在哪里呀?
    發(fā)表于 06-24 07:04

    第六章 外部中斷

    本章介紹W55MH32的IO口作為外部中斷輸入的使用。先闡述了NVIC(嵌套向量中斷控制器) 的結(jié)構(gòu)、寄存器、優(yōu)先級(jí)及相關(guān)函數(shù),再說明EXTI(外部中斷和事件控制器)的功能??驁D及IO口與
    的頭像 發(fā)表于 05-26 16:27 ?1707次閱讀
    第六章 外部<b class='flag-5'>中斷</b>

    CY7C65215A 的 WAKEUP 和 SUSPEND 引腳應(yīng)如何連接?

    對(duì)于非電池模式,CY7C65215A 的 WAKEUP 和 SUSPEND 引腳應(yīng)如何連接? 當(dāng)我嘗試通過 USB 訪問 SPI 時(shí),遇到了超時(shí)問題。
    發(fā)表于 05-19 07:22
    祁连县| 江津市| 岑巩县| 金华市| 边坝县| 青海省| 元氏县| 伊宁县| 靖边县| 襄城县| 祁连县| 贵港市| 贵定县| 桃江县| 湘阴县| 松原市| 蓬安县| 长治县| 浦城县| 汶上县| 通许县| 尼木县| 资溪县| 新郑市| 台江县| 华容县| 方正县| 庆阳市| 宿松县| 榆林市| 安国市| 军事| 张北县| 长顺县| 闸北区| 肃南| 奇台县| 长武县| 壤塘县| 舞阳县| 肃北|