日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯網營銷解決方案
白話說Java線程(二)—讓線程優(yōu)雅的停下來

一、前言

創(chuàng)新互聯服務項目包括麗水網站建設、麗水網站制作、麗水網頁制作以及麗水網絡營銷策劃等。多年來,我們專注于互聯網行業(yè),利用自身積累的技術優(yōu)勢、行業(yè)經驗、深度合作伙伴關系等,向廣大中小型企業(yè)、政府機構等提供互聯網行業(yè)的解決方案,麗水網站推廣取得了明顯的社會效益與經濟效益。目前,我們服務的客戶以成都為中心已經輻射到麗水省份的部分城市,未來相信會繼續(xù)擴大服務區(qū)域并繼續(xù)獲得客戶的支持與信任!

繼續(xù)接之前 Java 多線程的內容,之前講解了 Java 下多線程的使用,有興趣的可以先看看《白話說 Java 線程(一)之讓線程先跑起來》。但是能舞的起來是徒弟,能停的優(yōu)雅才是師傅。

接下來讓我們看看,如何優(yōu)雅的停止一個線程。

二、全的停止線程

2.1、安全停止涉及到的方法

當開啟一起線程去執(zhí)行任務之后,如果需要被停止,意味著它將放棄當前正在進行的操作。而在 Java 中,停止一個線程并不像 return 一個方法一樣干脆利落,想要安全的停止線程,需要一些跟優(yōu)雅的技巧。

如果想要安全的停止一個線程,需要借助 Thread.interrupt() 方法,它的本意是停止、終止的意思,但是實際上,它并不會直接終止掉一個正在運行的進程,而是在當前線程中,打一個需要"被停止"的標簽,而是否停止應該由當前線程自己決定,所以這也決定了我們需要在編寫 Thread 或者 Runnable 代碼的時候,有更高的要求,要明確自己如何被安全的停止。

interrupt() 的解釋確實挺多,接下來看看它是如何使用的。

既然 interrupt() 只是為我們對當前線程做了一個簡單的停止標記,而 JDK 同時也為我們提供了獲取這個標記值的 API。

  • Thread.interrupted():檢查當前運行這段代碼的線程,是否已經被停止。
  • this.isInterrupted():檢查當前 this 指定的線程,是否已經被停止。

通過源碼可以看到它們的區(qū)別,interrupted() 是一個 static 的方法,并且操作的是當前代碼運行的當前線程,而 isInterrupted() 方法缺失操作的是指定線程。它們最終都會調用 isInterrupted(boolean) 的方法。

再來看看這個方法。

可以看到,這個方法是一個 native 的方法,參數表示是否需要清理這個 Interrupted 的狀態(tài)。

2.2、具體看看這些方法的用處

舉個例子看看如何區(qū)分這兩個方法:

1 為停止,表示檢查的是 mt 這個線程,而 2 為沒停止,是因為檢查的是當前運行環(huán)境的線程,即為主線程。

這個例子本身沒問題,也講清楚了原本的意思。但是實際上,interrupt() 方法和 interrupted() 方法并不是線程安全的,也就是說,如果使用 interrupt() 方法停止了一個線程,立即使用 interrupted() 方法去檢查,可能會回去到還沒有被停止的結果。

前面介紹到,interrupt() 和 isInterrupted() 方法最終都會調用一個 native 的 isInterrupted(boolean) 的方法,這個方法的參數主要是為了確定是否需要清理 interrupted 的狀態(tài)。

下面舉兩個例子就清楚了。

先看看 Thread.interrupted()。

可以看到,***次標記為 true,但是獲取完之后,立即就被清理掉了 interrupt 狀態(tài),再去獲取,就標記為 false。再看看 isInterrupted() ,它是不會清理掉狀態(tài)的。

2.3、需要安全停止的線程

那么繼續(xù)改造一下上面的例子,如果想在線程被停止之后,立即停止掉循環(huán),就可以在循環(huán)中,每次調用都檢查一下當前線程是否已經被停止了。如果被停止了,直接 return 出去,或者做一些清理工作再退出。

2.4、在sleep的時候,停止線程會發(fā)生什么

當前線程有可能在運行狀態(tài),也可能在 sleep 的狀態(tài),如果在 sleep 的狀態(tài)下,interrupt 一個線程,會發(fā)生什么?

從調用 sleep 的時候就應該發(fā)現,它是會拋出一個 InterruptedException 異常的,這里就是專門為了捕捉在 sleep 的時候,被 interrupt 的情況。如果觸發(fā),將進入 catch。并且置換 interrupt 狀態(tài)為 false ,所以這里觸發(fā)了到 sleep 的 catch 的時候,一定要有后續(xù)的操作,不要再依賴那兩個判斷線程終止的方法來判斷了。

三、如何非安全的停止線程

既然推薦用安全的方式來停止線程,那么不安全的方式又需要怎么做呢?不安全的方式其實本身也不推薦使用,但是研究一下為什么不安全也有利于我們理解線程安全。

不安全的方式,就涉及到 Thread 的幾個已經被標記為 @Deprecated 的方法,就是說,已經被廢棄了,可能引發(fā)不可預料的問題,不推薦使用。

這個方法就是 stop() 方法,和名稱一樣,它的作用就是停止線程。

stop() 能不能做到立即停止線程?

能,除了它的一些不可能預料的數據問題之外,stop() 方法真的非常的好用,停止線程可以做到簡單直接,直接被停止之后,后面的代碼根本不會得到執(zhí)行,這樣會導致一些清理工作沒法完成,并且 stop() 會直接釋放當前獲取到的鎖,而如果當前正好在修改加鎖的數據的時候,被強制停止了,就會導致數據被改了一半,導致數據不一致的情況。

既然不推薦使用,那就簡單舉個例子,不再寫 demo 了。

假設一個人做生意,賣書,庫房里存了需要賣的書,每次的流程是從庫房里拿出來一本書,賣出去之后,把錢存入銀行賬戶,再去取一本書繼續(xù)賣。假設有一天,這個人從庫房取了一本書賣出去了,正在去銀行存錢的路上,被警察逮捕了(stop),接下來他就沒辦法完成去銀行存錢的任務了。這個時候對書的庫存和銀行賬戶上的金額,就對不上了,因為出庫了一本書,缺沒有相應的金錢入賬。這樣的一個數據不一致,就是線程不安全。當然,實際項目中,這種數據操作都是以事務的形式存在的,一旦失敗就會回滾事務,讓數據保持一致。

有一點需要注意一下,stop() 方法的時候,會觸發(fā) ThreadDead 異常,但是它不需要被顯示 Catch 住,大家只需要知道有這么個概念就可以了。

四、結語

到現在基本上就講解清楚了子線程的創(chuàng)建和停止。既然已經被廢棄的方法,***還是不要去使用它,建議使用安全的方式去停止線程。

【本文為專欄作者“張旸”的原創(chuàng)稿件,轉載請通過微信公眾號聯系作者獲取授權】


網站欄目:白話說Java線程(二)—讓線程優(yōu)雅的停下來
分享鏈接:http://www.dlmjj.cn/article/djpjdjd.html