在java多线程里,启动一个线程很简单,那就是start,但是要停止一个线程就没那么简单了。首先想到的肯定是stop,但是很遗憾,stop方法已经被废弃,因为用stop是强制让线程停止,可能使一些清理性工作得不到完成。另外一个情况就是对锁定的对象进行了解锁,导致数据得不到同步的处理,出现数据不一致的问题。
那么,正确的停止线程的方法是什么呢?答案是用interrupted方法。但是,请注意,interrupted方法并不会立即停止线程,而是仅仅给线程打了一个停止的标记,并不是真正停止线程。这个标记有什么用呢?这个标记是在线程里自己判断用的,也就是说,用这种方式停止线程,还要在线程线程里用this.interrupted()方法判断是否为停止标志,是的话则用抛出异常或者return两种方式来停止。
另外有一点需要注意的是,判断是否停止的方法有两种,this.interrupted()和this.isInterrupted()。这两个方法都是判断是否当前线程是否停止,区别是this.interrupted()执行后会具有将状态标志清除为false的功能,this.isInterrupted()则不会。
总的来说,用抛出异常的方式比用return的方式来停止线程要好。因为在catch块中可以对异常的信息进行相关的处理,而且使用异常流能更好,更方便的控制程序的运行流程,不至于代码中出现很多个return;造成污染。
看下面的代码示例。
public class MyThread extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 500000; i++) {
System.out.println(System.currentTimeMillis() + " i= "+i);
}
}
}
- public class MyThread extends Thread {
- @Override
- public void run() {
- super.run();
- for (int i = 0; i < 500000; i++) {
- System.out.println(System.currentTimeMillis() + " i= "+i);
- }
- }
- }
public class MyThread extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 500000; i++) {
System.out.println(System.currentTimeMillis() + " i= "+i);
}
}
}
public class MyThread2 extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 500000; i++) {
if (this.isInterrupted()) {
// 使用interrupt并未真正停止一个线程,而是给一个停止的标识,需要判断,break手动停止。
System.out.println("已中止");
break;
}
System.out.println(System.currentTimeMillis() + " i= "+i);
}
System.out.println("for下面被执行");
}
}
- public class MyThread2 extends Thread {
- @Override
- public void run() {
- super.run();
- for (int i = 0; i < 500000; i++) {
- if (this.isInterrupted()) {
- // 使用interrupt并未真正停止一个线程,而是给一个停止的标识,需要判断,break手动停止。
- System.out.println("已中止");
- break;
- }
- System.out.println(System.currentTimeMillis() + " i= "+i);
- }
- System.out.println("for下面被执行");
- }
- }
public class MyThread2 extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 500000; i++) {
if (this.isInterrupted()) {
// 使用interrupt并未真正停止一个线程,而是给一个停止的标识,需要判断,break手动停止。
System.out.println("已中止");
break;
}
System.out.println(System.currentTimeMillis() + " i= "+i);
}
System.out.println("for下面被执行");
}
}
public class MyThread3 extends Thread {
@Override
public void run() {
super.run();
try {
for (int i = 0; i < 500000; i++) {
if (this.isInterrupted()) {
// 使用interrupt并未真正停止一个线程,而是给一个停止的标识,一般用异常的方式来停止。
// 使用异常方法来停止比用return好
System.out.println("已中止");
throw new InterruptedException();
}
System.out.println(System.currentTimeMillis() + " i= " + i);
}
System.out.println("for下面被执行");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- public class MyThread3 extends Thread {
- @Override
- public void run() {
- super.run();
- try {
- for (int i = 0; i < 500000; i++) {
- if (this.isInterrupted()) {
- // 使用interrupt并未真正停止一个线程,而是给一个停止的标识,一般用异常的方式来停止。
- // 使用异常方法来停止比用return好
- System.out.println("已中止");
- throw new InterruptedException();
- }
- System.out.println(System.currentTimeMillis() + " i= " + i);
- }
- System.out.println("for下面被执行");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
public class MyThread3 extends Thread {
@Override
public void run() {
super.run();
try {
for (int i = 0; i < 500000; i++) {
if (this.isInterrupted()) {
// 使用interrupt并未真正停止一个线程,而是给一个停止的标识,一般用异常的方式来停止。
// 使用异常方法来停止比用return好
System.out.println("已中止");
throw new InterruptedException();
}
System.out.println(System.currentTimeMillis() + " i= " + i);
}
System.out.println("for下面被执行");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MyThread4 extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 500000; i++) {
if (this.isInterrupted()) {
// 使用interrupt并未真正停止一个线程,而是给一个停止的标识,需要判断,return也能停止。
System.out.println("已中止");
return;
}
System.out.println(System.currentTimeMillis() + " i= "+i);
}
System.out.println("for下面被执行");
}
}
- public class MyThread4 extends Thread {
- @Override
- public void run() {
- super.run();
- for (int i = 0; i < 500000; i++) {
- if (this.isInterrupted()) {
- // 使用interrupt并未真正停止一个线程,而是给一个停止的标识,需要判断,return也能停止。
- System.out.println("已中止");
- return;
- }
- System.out.println(System.currentTimeMillis() + " i= "+i);
- }
- System.out.println("for下面被执行");
- }
- }
public class MyThread4 extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 500000; i++) {
if (this.isInterrupted()) {
// 使用interrupt并未真正停止一个线程,而是给一个停止的标识,需要判断,return也能停止。
System.out.println("已中止");
return;
}
System.out.println(System.currentTimeMillis() + " i= "+i);
}
System.out.println("for下面被执行");
}
}
public class Main {
public static void main(String[] args) {
// 停止线程不推荐用stop,stop是暴力停止,可能会带来数据不一致的问题。
// MyThread myThread = new MyThread();
// MyThread2 myThread = new MyThread2();
// MyThread3 myThread = new MyThread3();
MyThread4 myThread = new MyThread4();
myThread.start();
try {
Thread.sleep(2000);
myThread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- public class Main {
- public static void main(String[] args) {
- // 停止线程不推荐用stop,stop是暴力停止,可能会带来数据不一致的问题。
- // MyThread myThread = new MyThread();
- // MyThread2 myThread = new MyThread2();
- // MyThread3 myThread = new MyThread3();
- MyThread4 myThread = new MyThread4();
- myThread.start();
- try {
- Thread.sleep(2000);
- myThread.interrupt();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
public class Main {
public static void main(String[] args) {
// 停止线程不推荐用stop,stop是暴力停止,可能会带来数据不一致的问题。
// MyThread myThread = new MyThread();
// MyThread2 myThread = new MyThread2();
// MyThread3 myThread = new MyThread3();
MyThread4 myThread = new MyThread4();
myThread.start();
try {
Thread.sleep(2000);
myThread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}