我正在读一本书,上面写着不使用这样的代码:
private volatile Thread myThread;
....
myThread.stop();
相反应该使用:
if (myThread != null ) {
Thread dummy = myThread;
myThread = null;
dummy.interrupt();
}
不幸的是,这个主题还没有详细说明......有人可以解释一下吗?
答案 0 :(得分:3)
您可以找到一个很好的答案,说明为什么不使用stop()
方法here。您可以使用此变量保存布尔变量并无限循环,而不是使用此方法:
public class MyRunnable extends Runnable {
public volatile boolean keepRunning = true;
public void run() {
while (keepRunning) {
... // do what you have to do
}
}
}
一旦决定完成,您只需将keepRunning
变量设置为false即可。然后你的线程将:
- 完成剩下的步骤
- 终止
就像你以受控方式完成工作而不使用不安全的stop()
方法。
答案 1 :(得分:3)
stop()
已弃用。永远不要永远不要使用stop()
。您可以改为使用java concurrency。
来自Javadoc:
这种方法本质上是不安全的。使用Thread.stop停止一个线程会导致它解锁它已锁定的所有监视器(这是未经检查的ThreadDeath异常向上传播的自然结果)。如果先前受这些监视器保护的任何对象处于不一致状态,则受损对象对其他线程可见,可能导致任意行为。 stop的许多用法应该被简单修改某个变量的代码替换,以指示目标线程应该停止运行。目标线程应该定期检查此变量,并且如果变量指示它将停止运行,则以有序的方式从其run方法返回。如果目标线程等待很长时间(例如,在条件变量上),则应使用中断方法来中断等待。
查看Java Concurrency in Practice第7章(取消和关闭)
答案 2 :(得分:1)
Thread.stop()是deprecated。不要使用它。为什么?阅读Java Thread Primitive Deprecation
答案 3 :(得分:1)
不推荐使用Thread.stop,不应使用它(更多信息here)。
示例代码似乎使对“myThread”的引用无效,然后发出信号让它中断。假设“myThread”是对你的线程的唯一引用,并且线程中运行的代码正确处理中断请求(而不是忽略它们),当“if(myThread!= null)”时,线程将结束并有资格进行垃圾回收。 “代码块完成。
答案 4 :(得分:1)
尽管不推荐使用Thread.stop。知道使用Thread.stop可以绕过copmiler检查的异常控制也很有用。例如,
public void doSomething(){
Thread.currentThread().stop(new IOException());
}
这将抛出IOException。 IOException是一个经过检查的已检查异常,编译器通常会强制客户端捕获或让方法抛出它。这里doSomething抛出一个未经检查的IOException
答案 5 :(得分:1)
每个人都提供了很好的信息,说明为什么不调用Thread.stop()。
谢尔盖的评论修正了我给出的关于interrupt()处理的错误信息。我更喜欢使用信号标志,就像lewap的答案一样。就像谢尔盖所说的那样,interrupt()是为了唤醒一个被阻塞操作的线程。如果你的线程没有调用任何阻塞操作,那么interrupt()实际上不会终止该线程。你的线程虽然可以调用isInterrupted()来查看是否已经调用了中断(基本上是一个信号标志)。
回到你的书的例子,我不喜欢它。
if (myThread != null ) {
Thread dummy = myThread;
myThread = null;
dummy.interrupt();
}
在此示例中,没有充分的理由复制到虚拟变量。你很困惑。
本书作者可能正在考虑尝试阻止其他线程同时尝试中断同一个线程,但是中断代码不是线程安全的(“检查是否为null并设置为null”操作不是原子的),所以编写虚拟任务是在不增加实际线程安全性的情况下弄脏水域。
答案 6 :(得分:1)
除了@Paweloque建议的内容(这是一种完美的方式)之外,还有另一种方法可以使用stop()建议here
错误的方式:
假设您的applet包含以下启动,停止和运行方法:
private Thread blinker;
public void start() {
blinker = new Thread(this);
blinker.start();
}
public void stop() {
blinker.stop(); // UNSAFE!
}
public void run() {
Thread thisThread = Thread.currentThread();
while (true) {
try {
thisThread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
正确的方式
您可以通过将applet的stop和run方法替换为以下内容来避免使用Thread.stop: private volatile Thread blinker;
public void stop() {
blinker = null;
}
public void run() {
Thread thisThread = Thread.currentThread();
while (blinker == thisThread) {
try {
thisThread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}