java為什么不要用stop方法停止線程

本篇內(nèi)容主要講解“java為什么不要用stop方法停止線程”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“java為什么不要用stop方法停止線程”吧!

創(chuàng)新互聯(lián)專注于永興企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站設(shè)計(jì),商城建設(shè)。永興網(wǎng)站建設(shè)公司,為永興等地區(qū)提供建站服務(wù)。全流程按需網(wǎng)站策劃,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

         

線程啟動(dòng)完畢后,在運(yùn)行時(shí)可能需要終止,Java提供的終止方法只有一個(gè)stop,但是我不建議使用這個(gè)方法,因?yàn)樗幸韵氯齻€(gè)問題:(1)stop方法是過時(shí)的從Java編碼規(guī)則來說,已經(jīng)過時(shí)的方法不建議采用。(2)stop方法會(huì)導(dǎo)致代碼邏輯不完整stop方法是一種“惡意”的中斷,一旦執(zhí)行stop方法,即終止當(dāng)前正在運(yùn)行的線程,不管線程邏輯是否完整,這是非常危險(xiǎn)的??慈缦碌拇a:

java為什么不要用stop方法停止線程

這段代碼的邏輯是這樣的:子線程是一個(gè)匿名內(nèi)部類,它的run方法在執(zhí)行時(shí)會(huì)休眠1秒鐘,然后再執(zhí)行后續(xù)的邏輯,而主線程則是休眠0.1秒后終止子線程的運(yùn)行,也就是說,JVM在執(zhí)行thread.stop()時(shí),子線程還在執(zhí)行sleep(1000),此時(shí)stop方法會(huì)清除棧內(nèi)信息,結(jié)束該線程,這也就導(dǎo)致了run方法的邏輯不完整,輸出語句println代表的是一段邏輯,可能非常重要,比如子線程的主邏輯、資源回收、情景初始化等,但是因?yàn)閟top線程了,這些就都不再執(zhí)行,于是就產(chǎn)生了業(yè)務(wù)邏輯不完整的情況。這是極度危險(xiǎn)的,因?yàn)槲覀儾恢雷泳€程會(huì)在什么時(shí)候被終止,stop連基本的邏輯完整性都無法保證。而且此種操作也是非常隱蔽的,子線程執(zhí)行到何處會(huì)被關(guān)閉很難定位,這為以后的維護(hù)帶來了很多麻煩。(3)stop方法會(huì)破壞原子邏輯多線程為了解決共享資源搶占的問題,使用了鎖概念,避免資源不同步,但是正因此原因,stop方法卻會(huì)帶來更大的麻煩:它會(huì)丟棄所有的鎖,導(dǎo)致原子邏輯受損。例如有這樣一段程序:

java為什么不要用stop方法停止線程

MultiThread實(shí)現(xiàn)了Runnable接口,具備多線程能力,其中run方法中加上了synchronized代碼塊,表示內(nèi)部是原子邏輯,它會(huì)先自增然后再自減少,按照synchronized同步代碼塊的規(guī)則來處理,此時(shí)無論啟動(dòng)多少個(gè)線程,打印出來的結(jié)果都應(yīng)該是a=0,但是如果有一個(gè)正在執(zhí)行的線程被stop,就會(huì)破壞這種原子邏輯,代碼如下:

java為什么不要用stop方法停止線程

首先要說明的是所有線程共享了一個(gè)MultiThread的實(shí)例變量t,其次由于在run方法中加入了同步代碼塊,所以只能有一個(gè)線程進(jìn)入到synchronized塊中。此段代碼的執(zhí)行順序如下:1)線程t1啟動(dòng),并執(zhí)行run方法,由于沒有其他線程持同步代碼塊的鎖,所以t1線程執(zhí)行自加后執(zhí)行到sleep方法即開始休眠,此時(shí)a=1。2)JVM又啟動(dòng)了5個(gè)線程,也同時(shí)運(yùn)行run方法,由于synchronized關(guān)鍵字的阻塞作用,這5個(gè)線程不能執(zhí)行自增和自減操作,等待t1線程鎖釋放。3)主線程執(zhí)行了t1.stop方法,終止了t1線程,注意,由于a變量是所有線程共享的,所以其他5個(gè)線程獲得的a變量也是1。4)其他5個(gè)線程依次獲得CPU執(zhí)行機(jī)會(huì),打印出a值。分析了這么多,相信讀者也明白了輸出的結(jié)果,結(jié)果如下:

java為什么不要用stop方法停止線程

原本期望synchronized同步代碼塊中的邏輯都是原子邏輯,不受外界線程的干擾,但是結(jié)果卻出現(xiàn)原子邏輯被破壞的情況,這也是stop方法被廢棄的一個(gè)重要原因:破壞了原子邏輯。既然終止一個(gè)線程不能使用stop方法,那怎樣才能終止一個(gè)正在運(yùn)行的線程呢?答案也很簡(jiǎn)單,使用自定義的標(biāo)志位決定線程的執(zhí)行情況,代碼如下:

java為什么不要用stop方法停止線程

這是很簡(jiǎn)單的辦法,在線程體中判斷是否需要停止運(yùn)行,即可保證線程體的邏輯完整性,而且也不會(huì)破壞原子邏輯??赡苡凶x者對(duì)Java API比較熟悉,于是提出疑問:Thread不是還提供了interrupt中斷線程的方法嗎?這個(gè)方法可不是過時(shí)方法,那可以使用嗎?它可以終止一個(gè)線程嗎?非常好的問題,interrupt,名字看上去很像是終止一個(gè)線程的方法,但是我可以很明確地告訴你,它不是,它不能終止一個(gè)正在執(zhí)行著的線程,它只是修改中斷標(biāo)志而已,例如下面一段代碼:

java為什么不要用stop方法停止線程

執(zhí)行這段代碼,你會(huì)發(fā)現(xiàn)一直有Running在輸出,永遠(yuǎn)不會(huì)停止,似乎執(zhí)行了interrupt沒有任何變化,那是因?yàn)閕nterrupt方法不能終止一個(gè)線程狀態(tài),它只會(huì)改變中斷標(biāo)志位(如果在t1.interrupt()前后輸出t1.isInterrupted()則會(huì)發(fā)現(xiàn)分別輸出了false和true),如果需要終止該線程,還需要自行進(jìn)行判斷,例如我們可以使用interrupt編寫出更加簡(jiǎn)潔、安全的終止線程代碼

java為什么不要用stop方法停止線程

總之,如果期望終止一個(gè)正在運(yùn)行的線程,則不能使用已經(jīng)過時(shí)的stop方法,需要自行編碼實(shí)現(xiàn),如此即可保證原子邏輯不被破壞,代碼邏輯不會(huì)出現(xiàn)異常。當(dāng)然,如果我們使用的是線程池(比如ThreadPoolExecutor類),那么可以通過shutdown方法逐步關(guān)閉池中的線程,它采用的是比較溫和、安全的關(guān)閉線程方法,完全不會(huì)產(chǎn)生類似stop方法的弊端。


到此,相信大家對(duì)“java為什么不要用stop方法停止線程”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

網(wǎng)頁名稱:java為什么不要用stop方法停止線程
鏈接地址:http://bm7419.com/article48/gocdhp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)公司、ChatGPT外貿(mào)網(wǎng)站建設(shè)、Google、網(wǎng)站營銷、微信公眾號(hào)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)