三种方法
1)stop(),这个方法不安全,所以这方法已过期作废了,不建议使用
2)使用退出标志,使线程正常退出,也就是当run方法完成后线程终止
3)使用interrupt()方法中断线程,但这个方法不会终止一个正在运行的线程,还需要加入一个判断才可以完成线程停止
interrupt()仅是停止标志
interrupt()只是一个停止标志,并不真正停止线程
package com.myThread;
public class Thread1 extends Thread {
public Thread1() {
}
@Override
public void run() {
super.run();
for(int i = 0;i<5000000;i++){
System.out.println(i);
}
}
}
package com.test;
import com.myThread.Thread1;
public class Test1 {
public static void main(String[] args) throws InterruptedException {
//测试1
Thread1 thread1 = new Thread1();
thread1.start();
Thread.sleep(5000);
thread1.interrupt();
}
}
完全没有停止
判断是否是停止状态
Java提供了两种方法
- interrupted():当前线程(currentThread)是否中断;
- isInterrupted():执行线程是否中断;
package com.myThread;
public class Thread1 extends Thread {
public Thread1() {
}
@Override
public void run() {
super.run();
for(int i = 0;i<5000000;i++){
//System.out.println("i="+(i+1));
}
}
}
package com.test;
import com.myThread.Thread1;
public class Test1 {
public static void main(String[] args) throws InterruptedException {
//测试1
Thread1 thread1 = new Thread1();
thread1.start();
thread1.interrupt();
System.out.println(thread1.interrupted());
System.out.println(thread1.interrupted());
//测试2
Thread.currentThread().interrupt();
System.out.println(Thread.interrupted());
System.out.println(Thread.interrupted());
// 测试3
Thread1 thread1 = new Thread1();
thread1.start();
thread1.interrupt();
System.out.println(thread1.isInterrupted());
System.out.println(thread1.isInterrupted());
}
}
测试1打印结果
false
false
测试2打印结果
true
false
测试3打印结果
true
true
测试1分析:
因为interrupt()源码
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
这是一个静态方法,而thread1.interrupted()中的thread1继承的是Thread类,所以返回的是判断当前线程是否停止的结果,而当前线程是main,而main一直都在运行,所以返回都是false
测试2分析:
调用了Thread.currentThread().interrupt();所以当前线程即main已经设置了中断状态,为什么第二个返回的是false,因为第一次执行之后会清除中断标志,所以第二次返回false
测试3分析
isInterrupted()不是一个静态方法,并且执行完之后不会清除中断状态标志
总结:
interrupted()判断当前线程是否是中断状态,并在执行后清除该状态标志
isInterrupted()仅仅判断线程对象时候是中断状态
休眠中停止
其实sleep()需要捕捉InterruptedException就知道休眠中不能停止,还是来测试一下
package com.myThread;
public class Thread3 extends Thread {
public Thread3() {
}
@Override
public void run() {
try {
System.out.println("Thread3 run begin");
Thread.sleep(50000);
System.out.println("Thread3 run end");
} catch (InterruptedException e) {
System.out.println("Thread3 catch e");
e.printStackTrace();
}
}
}
package com.test;
import com.myThread.Thread3;
public class Test3 {
public static void main(String[] args) {
// 测试1
try {
Thread3 thread3 = new Thread3();
thread3.start();
Thread.sleep(2000);
thread3.interrupt();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
测试1打印结果
Thread3 run begin
Thread3 catch e
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.myThread.Thread3.run(Thread3.java:12)
异常中断法
package com.test;
import com.myThread.Thread2;
public class Test2 {
public static void main(String[] args) throws InterruptedException {
// 测试1
Thread2 thread2 = new Thread2();
thread2.start();
Thread.sleep(500);
thread2.interrupt();
System.out.println("main 结束");
// 测试2
Thread2 thread2 = new Thread2();
thread2.start();
Thread.sleep(50);
thread2.interrupt();
System.out.println("main 结束");
}
}
测试1打印结果
499996
499997
499998
499999
这里是for下面
main 结束
测试2打印结果
2775
2776
2777
2778
我要停止了
这里是异常捕捉,中断线程
main 结束
java.lang.Exception
at com.myThread.Thread2.run(Thread2.java:16)
注意:Thread.sleep(5000);这里的数值根据自己计算机的处理速度来调
return中断法
package com.myThread;
public class Thread4 extends Thread {
public Thread4() {
}
@Override
public void run() {
super.run();
for (int i = 0; i < 500000; i++) {
System.out.println(i);
if (this.isInterrupted()) {
System.out.println("我要停止了");
return;
}
}
System.out.println("这里是for下面");
}
}
package com.test;
import com.myThread.Thread4;
public class Test4 {
public static void main(String[] args) throws InterruptedException {
// 测试1
// Thread4 thread4 = new Thread4();
// thread4.start();
// Thread.sleep(5000);
// thread4.interrupt();
// System.out.println("main 结束");
// 测试2
Thread4 thread4 = new Thread4();
thread4.start();
Thread.sleep(50);
thread4.interrupt();
System.out.println("main 结束");
}
}
测试1打印结果
499997
499998
499999
这里是for下面
main 结束
测试2打印结果
3460
3461
3462
3463
我要停止了
main 结束
异常和return的比较
都能停止线程,但是建议使用异常中断,以为catch能捕获异常并且将异常向上抛,使线程停止事件得到传播
使用stop()造成数据不一致
stop()方法已经作废,使用stop()可能会使一些后续工作得不到完成,另外也可能使对锁定对象进行“解锁”,导致数据得不到同步的处理。
stop()方法会抛出java.lang.ThreadDeath的异常,但是不需要捕捉
package com.myObject;
public class Object5 {
private String name = "a";
private String password = "aa";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
synchronized public void evalute(String name, String password) {
try {
this.name = name;
Thread.sleep(50000);
this.password = password;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public String toString() {
return "Object5 [name=" + name + ", password=" + password + "]";
}
}
package com.myThread;
import com.myObject.Object5;
public class Thread5 extends Thread {
private Object5 object5;
public Thread5(Object5 object5) {
this.object5 = object5;
}
@Override
public void run() {
super.run();
object5.evalute("b", "bb");
}
}
package com.test;
import com.myObject.Object5;
import com.myThread.Thread5;
public class Test5 {
public static void main(String[] args) throws InterruptedException {
// 测试1
Object5 object5 = new Object5();
Thread5 thread5 = new Thread5(object5);
thread5.start();
Thread.sleep(500);
thread5.stop();
System.out.println(object5.toString());
}
}
测试1打印结果
Object5 [name=b, password=aa]