不提倡的stop()方法
臭名昭著的stop()停止線程的方法已不提倡使用了,原因是什么呢?
當在一個線程對象上調用stop()方法時,這個線程對象所運行的線程就會立即停止,并拋出特殊的ThreadDeath()異常。這里的“立即”因為太“立即”了,
假如一個線程正在執行:
,一個測試類,ThreadDemo
這樣ThreadDemo調用interrupt()方法,isInterrupted()為true,就會退出運行。但是如果線程正在執行wait,sleep,join方法,你調用interrupt()方法,這個邏輯就不完全了。
我們可以這樣處理:
這個錯誤情況的實例代碼
ThreadA
public
class
ThreadA
extends
Thread
{
int
count
=
0
;
public
void
run()
{
System.out.println(getName()
+
"
將要運行...
"
);
while
(
!
this
.isInterrupted())
{
System.out.println(getName()
+
"
運行中
"
+
count
++
);
try
{
Thread.sleep(
400
);
}
catch
(InterruptedExceptione)
{
System.out.println(getName()
+
"
從阻塞中退出...
"
);
System.out.println(
"
this.isInterrupted()=
"
+
this
.isInterrupted());
}
}
System.out.println(getName()
+
"
已經終止!
"
);
}
}
ThreadDemo
public
class
ThreadDemo
{
public
static
void
main(Stringargv[])
throws
InterruptedException
{
ThreadAta
=
new
ThreadA();
ta.setName(
"
ThreadA
"
);
ta.start();
Thread.sleep(
2000
);
System.out.println(ta.getName()
+
"
正在被中斷...
"
);
ta.interrupt();
System.out.println(
"
ta.isInterrupted()=
"
+
ta.isInterrupted());
}
}
那么如何能確保線程真正停止?在線程同步的時候我們有一個叫“二次惰性檢測”(double check),能在提高效率的基礎上又確保線程真正中同步控制中。那么我把線程正確退出的方法稱為“雙重安全退出”,即不以isInterrupted ()為循環條件。而以一個標記作為循環條件:
正確的ThreadA代碼是:
public
class
ThreadA
extends
Thread
{
private
boolean
isInterrupted
=
false
;
int
count
=
0
;
public
void
interrupt()
{
isInterrupted
=
true
;
super
.interrupt();
}
public
void
run()
{
System.out.println(getName()
+
"
將要運行...
"
);
while
(
!
isInterrupted)
{
System.out.println(getName()
+
"
運行中
"
+
count
++
);
try
{
Thread.sleep(
400
);
}
catch
(InterruptedExceptione)
{
System.out.println(getName()
+
"
從阻塞中退出...
"
);
System.out.println(
"
this.isInterrupted()=
"
+
this
.isInterrupted());
}
}
System.out.println(getName()
+
"
已經終止!
"
);
}
}
臭名昭著的stop()停止線程的方法已不提倡使用了,原因是什么呢?
當在一個線程對象上調用stop()方法時,這個線程對象所運行的線程就會立即停止,并拋出特殊的ThreadDeath()異常。這里的“立即”因為太“立即”了,
假如一個線程正在執行:
synchronized void {
x = 3;
y = 4;
}
由于方法是同步的,多個線程訪問時總能保證x,y被同時賦值,而如果一個線程正在執行到x = 3;時,被調用了 stop()方法,即使在同步塊中,它也干脆地stop了,這樣就產生了不完整的殘廢數據。而多線程編程中最最基礎的條件要保證數據的完整性,所以請忘記 線程的stop方法,以后我們再也不要說“停止線程”了。
如何才能“結束”一個線程?
interupt()中斷線程
- 正常運行.
- 處理結束前的工作,也就是準備結束.
- 結束退出.
while(!isInterrupted()){
正常邏輯
}
,一個測試類,ThreadDemo
這樣ThreadDemo調用interrupt()方法,isInterrupted()為true,就會退出運行。但是如果線程正在執行wait,sleep,join方法,你調用interrupt()方法,這個邏輯就不完全了。
我們可以這樣處理:
public void run(){想一想,如果一個正在sleep的線程,在調用interrupt后,會如何?wait方法檢查到isInterrupted()為true,拋出異常, 而你又沒有處理。而一個拋出了InterruptedException的線程的狀態馬上就會被置為非中斷狀態,如果catch語句沒有處理異常,則下一 次循環中isInterrupted()為false,線程會繼續執行,可能你N次拋出異常,也無法讓線程停止。
while(!isInterrupted()){
try{
正常工作
}catch(InterruptedException e){
//nothing
}
}
}
}
這個錯誤情況的實例代碼
ThreadA

































那么如何能確保線程真正停止?在線程同步的時候我們有一個叫“二次惰性檢測”(double check),能在提高效率的基礎上又確保線程真正中同步控制中。那么我把線程正確退出的方法稱為“雙重安全退出”,即不以isInterrupted ()為循環條件。而以一個標記作為循環條件:
正確的ThreadA代碼是:



























更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
