您的位置:首页 > 其它

interrupted、isInterrupted

2018-01-24 16:23 162 查看
对于线程来说,动起来不是什么问题,但是如何让它停下来,就需要一些处理。

虽然stop、suspend、resume都可以使线程停下来,但是官方是不建议的,现在已经废弃了。

interrupt方法仅仅只是打了一个停止标记。

判断线程是否停止状态

interrupt

isInterrupted

public class Test148 {
public static void main(String[] args) {
MyThread33 mm = new MyThread33();
Thread t = new Thread(mm);
t.start();
t.interrupt();
System.out.println("Thread.currentThread().interrupted()"+Thread.currentThread().interrupted());//当前运行的是main,故false
System.out.println("t.interrupted()"+t.interrupted());
System.out.println("Thread.currentThread().isInterrupted()"+Thread.currentThread().isInterrupted());
System.out.println("t.isInterrupted()"+t.isInterrupted());//对线程t判断是否中断状态,true。
}
}

class MyThread33 extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0;i<10000;i++) {
System.out.println("*");
}
}

}


运行结果如下:



我们来分析一下,我们给线程t设置停止标志,interrupted方法,只是对当前正在运行的线程,判断是否中断状态,它不管调用对象;isInterrupted,是针对调用线程对象,来判断是否中断状态。

修改上述代码:

Thread.currentThread().interrupt();//我们给main线程设置中断标志
System.out.println("Thread.currentThread().interrupted()"+Thread.currentThread().interrupted());
System.out.println("Thread.currentThread().interrupted()"+Thread.currentThread().interrupted());


我们发现执行下来,第一个是true,因为当前的正在运行的线程对象是main,第二个是false,这里实际上,执行interrupt,如果是中断状态,会自动清除,所以是false。而isInterrupted,就不具备清除中断标志。验证代码修改如下:

t.interrupt();
System.out.println("t.isInterrupted()"+t.isInterrupted());//true
System.out.println("t.isInterrupted()"+t.isInterrupted());//true


牛刀小试

看看结合上面讲的如何让线程停下来。

public class Test148 {
public static void main(String[] args) {
MyThread33 mm = new MyThread33();
Thread t = new Thread(mm);
t.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.interrupt();
}
}

class MyThread33 extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0;i<10000;i++) {
//interrupted  上面讲过是针对当前正在运行的线程,判断是否有中断标志,这里的this,指的是
//MyThread33线程的实例,也就是mm。但是这时正在运行时线程t,
//看谁调用start。interrupted又不管谁调用,它只在现在正在运行的
System.out.println(this.getName());//Thread-0
if(Thread.currentThread().interrupted()) {
System.out.println("我要停止了");
break;

}
System.out.println(i);
}
}

}


在上面代码,还存在一个问题,就是如果for循环外面还有语句,那么这样的话,下面的语句还是会执行。在上面的代码做修改:

try {
for(int i = 0;i<10000;i++) {
//interrupted  上面讲过是针对当前正在运行的线程,判断是否有中断标志,这里的this,指的是
//MyThread33线程的实例,也就是mm。但是这时正在运行时线程t,
//看谁调用start。interrupted又不管谁调用,它只在现在正在运行的
System.out.println(this.getName());//Thread-0
if(Thread.currentThread().interrupted()) {
System.out.println("我要停止了"<
4000
/span>);
throw new InterruptedException();
}
System.out.println(i);
}
System.out.println("我在for外面");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


我们把执行体中需要执行的代码,放到一个异常的try中,当捕获这个异常的时候,程序代码是try中是不会往下执行,处理上面的问题,但是异常程序会让程序崩了。

线程在Sleep中停止

在这个操作中,一定要保证线程在Sleep的状态下,你去给他设置了停止标志,才会触发异常,如果Sleep状态结束,主线程才执行t.interrupt(),是不会影响的。

MyTask111 mt = new MyTask111();
Thread t  = new Thread(mt);
t.start();
/*try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
t.interrupt();
}
}
class MyTask111 implements Runnable{

@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println("我停止了");
e.printStackTrace();
}
}

}


我们之前就说过,Java已经抛弃stop方法,为啥呢,使用该方法停止线程,会造成数据不一致的问题,只要执行stop语句,是不管线程执行到哪,它立马停止。下面模拟该问题的发生。

public class Account {
private String username="a";
private String userpassword = "aa";
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpasswword() {
return userpassword;
}
public void setUserpasswword(String userpasswword) {
this.userpassword = userpasswword;
}

public String toString(String username,String userpassword) {
this.username = username;
try {
Thread.sleep(3000);//通过睡眠拖时间,给时间让主线程执行到stop
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.userpassword  = userpassword;
return  username+"   "+userpassword;
}

}


public class Test159 {
public static void main(String[] args) {
Account a = new Account();
MyThread990 mt = new MyThread990(a);
Thread t = new Thread(mt);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.stop();
System.out.println(a.getUsername()+"   "+a.getUserpasswword());
}
}
class MyThread990 implements Runnable{
private Account  useraccound;

public MyThread990(Account useraccound) {
super();
this.useraccound = useraccound;
}

@Override
public void run() {
// TODO Auto-generated method stub
useraccound.toString("b","bb");

}
}


上述结果是b aa ,可见执行属性值修改的时候,userpassword 并没有执行到,就stop了。

上面讲过来使用异常配合interrupt来停止异常,下面可以使用return加interrupt也可以实现。

public class Test160 {
public static void main(String[] args) {
Thread t = new Thread(new MyThread55());
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.interrupt();

}
}
class MyThread55 implements Runnable{
int i  = 0;
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
System.out.println(i++);
if(Thread.interrupted()) {
return;
}
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息