不提倡的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代码是:


























