java并发编程:为什么不要用stop方法停止线程
首先先看一段代码:
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
StopThread thread = new StopThread();
thread.start();
Thread.sleep(1000L);
thread.stop();
while (thread.isAlive()) {
}
thread.print();
}
private static class StopThread extends Thread {
private int x = 0;
private int y = 0;
@Override
public void run() {
synchronized (this) {
++x;
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
++y;
}
}
public void print() {
System.out.println("x=" + x + " y=" + y);
}
}
}
这段代码的本意是x和y要一起自增1,也就是x=1、y=1;然而这段代码输出如下
x=1 y=0
如果我们把主线程中的Thread.sleep(1000L);
代码注释掉,再次运行代码,代码输出如下
x=1 y=1
这其实才是我们想要得到的结果。由于任性调用stop方法,导致y还还没有自增线程就挂掉了,没有异常,也破坏了我们的预期。如果这种问题出现在我们的程序中,会引发难以预料的异常。因此这种不安全的方式很早就被废弃掉了。
正确的做法是让业务决定是否停止线程,这样才能保持业务的处理和线程停止结果的一致性。正常关闭线程的demo如下
public class MyRunnableMain {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
try {
Thread.sleep(10L * 1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
myRunnable.doStop();
}
}
class MyRunnable implements Runnable {
private boolean doStop = false;
public synchronized void doStop() {
this.doStop = true;
}
private synchronized boolean keepRunning() {
return !this.doStop;
}
@Override
public void run() {
while (keepRunning()) {
// keep doing what this thread should do.
System.out.println("Running");
try {
Thread.sleep(3L * 1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
结果就是
Running
Running
Running
Running
这样关闭线程才优雅。
注意:本文归作者所有,未经作者允许,不得转载