java中有3种方式能终止正在运行的线程:
1.run()方法运行完成,线程正常退出。
2.使用stop方法强行终止,但此方法已经过期,不推荐使用。
3.使用interrupt标记退出。
对线程使用interrupt怎么停不下来?
class Mythread extends Thread{
public void run(){
for(int i = 0; i < 50000; i++){
System.out.println("i=" + i);
}
}
}
public class Main {
public static void main(String[] args) {
try {
Mythread mythread = new Mythread();
mythread.start();
Thread.sleep(2000);
mythread.interrupt();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
运行结果:
从运行结果看出,线程并没有被停止,虽然我们用了interrupt方法。为什么会这样呢?因为线程调用此方法后,只是对线程做了标记,告诉线程你应该停下来了。究竟什么时候停下来,还需要被标记线程自己进一步处理。那如何能知道线程被提醒要停下来了呢?有两个方法interrupted()与isInterrupted()。
interrupted():测试当前线程是否被标记。
class Mythread extends Thread{
public void run(){
for(int i = 0; i < 50000; i++){
System.out.println("i=" + i);
}
}
}
public class Main {
public static void main(String[] args) {
try {
Mythread mythread = new Mythread();
mythread.start();
Thread.sleep(2000);
mythread.interrupt();
System.out.println("测试当前线程main是否被标记:" + mythread.interrupted());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
运行结果:
注意:当调用interrupted()测试当前线程后,如果线程之前被标记,则此标记被此方法读取后会被清除,如下:
public class Main {
public static void main(String[] args) {
try {
Thread.currentThread().interrupt();
System.out.println("测试当前线程main是否被标记:" + Thread.interrupted());
System.out.println("测试当前线程main是否被标记:" + Thread.interrupted());
Thread.sleep(1);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
运行结果:
isInterrupted():测试此线程(调用此方法的线程)是否被标记。
class Mythread extends Thread{
public void run(){
for(int i = 0; i < 50; i++){
System.out.println("i=" + i);
}
}
}
public class Main {
public static void main(String[] args) {
try {
Mythread mythread = new Mythread();
mythread.start();
//Thread.sleep(10); //此出调用sleep(10) 可能看到下面两个都是false
mythread.interrupt();
System.out.println("mythread是否被标记:" + mythread.isInterrupted());
System.out.println("mythread是否被标记:" + mythread.isInterrupted());
Thread.sleep(10);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
运行结果:
注意:刚开始我将main线程中的sleep放在了interrupt前(注释掉的地方),结果两个都是false,被标记的线程运行完成了,即使调用了interrupt ,也会返回false。
那么线程被interrupt标记后,需要让自己停下来
class Mythread extends Thread{
public void run(){
try {
for (int i = 0; i < 50; i++) {
if (this.interrupted()) {
System.out.println("被标记了,通过抛出异常退出。");
throw new InterruptedException();
}
System.out.println("i=" + i);
}
}catch (InterruptedException e){
System.out.println("catch");
e.printStackTrace();
}
}
}
public class Main {
public static void main(String[] args) {
try {
Mythread mythread = new Mythread();
mythread.start();
//Thread.sleep(10); //
mythread.interrupt();
System.out.println("mythread是否被标记:" + mythread.isInterrupted());
System.out.println("mythread是否被标记:" + mythread.isInterrupted());
Thread.sleep(10);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
运行结果:
使用stop(不推荐)终止线程
class MyThread{
private String username = "a";
private String password = "aa";
public synchronized String getUsername(){
return username;
}
public synchronized String getPassword(){
return password;
}
synchronized public void print_p_u(String password, String username){
try {
this.username = username;
Thread.sleep(100000);
this.password = password;
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
class test extends Thread{
private MyThread myThread;
public test(MyThread myThread){
this.myThread = myThread;
}
public void run(){
myThread.print_p_u("b", "bb");
}
}
public class Main {
public static void main(String[] args) {
try {
MyThread myThread = new MyThread();
test t = new test(myThread);
t.start();
Thread.sleep(500);
t.stop();
System.out.println(myThread.getUsername() + " "
+ myThread.getPassword());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
运行结果:
可以发现使用stop来终止线程后,可以立马终止线程,数据同步出现了错误;也可以发现线程被强行stop后,自动释放了持有的锁。