停止线程
- 使用退出标志,线程正常退出,也就是run方法完成后线程终止。
使用stop方法强行终止线程。(已经作废)- 使用interrput()中断线程
注意:interrupt()方法的使用效果并不像for+break语句那样,马上就停止循环。调用interrupt方法是在当前线程中打了一个停止标志,并不是真的停止线程。
interrupted() 和 isInterrupter() 判断线程是否中断
- interrupted():测试当前线程是否已经是中断状态,执行后具有将状态标志清除为false的功能。
- isInterrupted():测试线程Thread对象是否已经是中断状态,但是不清除状态位。
异常法停止线程
public class MyThread extends Thread {
public void run(){
super.run();
for(int i=0; i<500000; i++){
if(this.interrupted()) {
System.out.println("线程已经终止, for循环不再执行");
break;
}
System.out.println("i="+(i+1));
}
System.out.println("这是for循环外面的语句,也会被执行");
}
}
public class Run {
public static void main(String args[]){
Thread thread = new MyThread();
thread.start();
try {
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
output:
...
i=180136
i=180137
i=180138
i=180139
线程已经终止, for循环不再执行
这是for循环外面的语句,也会被执行
虽然停止了线程,但如果for语句下面还有语句,还是会继续运行的。
public class MyThread extends Thread {
public void run(){
super.run();
try {
for(int i=0; i<500000; i++){
if(this.interrupted()) {
System.out.println("线程已经终止, for循环不再执行");
throw new InterruptedException();
}
System.out.println("i="+(i+1));
}
System.out.println("这是for循环外面的语句,也会被执行");
} catch (InterruptedException e) {
System.out.println("进入MyThread.java类中的catch了。。。");
e.printStackTrace();
}
}
}
output:
...
i=203798
i=203799
i=203800
线程已经终止, for循环不再执行
进入MyThread.java类中的catch了。。。
java.lang.InterruptedException
at thread.MyThread.run(MyThread.java:13)
sleep()中停止线程
public class MyThread extends Thread {
public void run(){
super.run();
try {
System.out.println("线程开始。。。");
Thread.sleep(200000);
System.out.println("线程结束。");
} catch (InterruptedException e) {
System.out.println("在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:" + this.isInterrupted());
e.printStackTrace();
}
}
}
output:
线程开始。。。
在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at thread.MyThread.run(MyThread.java:12)
如果在sleep状态下停止某一线程,会进入catch语句,并且清除停止状态值,使之变为false。
废黜的stop()方法
- 废除stop()方法的理由
- 强制停止线程可能使一些清理性的工作得不到完成。
- 会对锁定对象“解锁”导致数据不一致。
使用return结合interrupt()停止线程
public class MyThread extends Thread {
public void run(){
while (true){
if(this.isInterrupted()){
System.out.println("线程被停止了!");
return;
}
System.out.println("Time: " + System.currentTimeMillis());
}
}
}
public class Run {
public static void main(String args[]) throws InterruptedException {
Thread thread = new MyThread();
thread.start();
Thread.sleep(2000);
thread.interrupt();
}
}
output:
...
Time: 1467072288503
Time: 1467072288503
Time: 1467072288503
线程被停止了!
建议使用“抛出异常”的方式来停止线程,因为在catch块中可以将异常上抛,使得线程停止的事件传播。
暂停线程
- suspend():暂停线程执行(已经作为)
- resume():恢复线程执行(已经作废)
- 作废理由一 独占
使用不当容易造成公共同步对象的独占,使得其他线程无法访问公共对象 - 作废理由二 不同步
和stop方法类似,容易导致数据不同步
yield()
作用是放弃当前CPU资源,将它让给其他任务去占用CPU执行时间。但是放弃的时间不确定,可能刚刚放弃马上又获得CPU时间片。
package ch01.test3;
public class MyThread extends Thread {
@Override
public void run() {
long beginTime = System.currentTimeMillis();
int count = 0;
for(int i = 0; i < 5000000; i++) {
//Thread.yield();
count = count + (i + 1);
}
long endTime = System.currentTimeMillis();
System.out.println("用时:"+ (endTime - beginTime) + "毫秒!");
}
}
class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
}
output:
用时:4毫秒!
去掉注释符号Thread.yield();
后,输出为:
用时:1753毫秒!