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();
        }
    }
}

运行结果:

java quartz 线程数 java线程interrupt_java多线程

 从运行结果看出,线程并没有被停止,虽然我们用了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();
        }
    }
}

运行结果:

java quartz 线程数 java线程interrupt_java quartz 线程数_02

注意:当调用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();
        }
    }
}

运行结果:

java quartz 线程数 java线程interrupt_i++_03

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();
        }
    }
}

运行结果:

java quartz 线程数 java线程interrupt_java多线程_04

注意:刚开始我将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();
        }
    }
}

运行结果:

java quartz 线程数 java线程interrupt_System_05

 使用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();
        }
    }
}

运行结果:

java quartz 线程数 java线程interrupt_java quartz 线程数_06

可以发现使用stop来终止线程后,可以立马终止线程,数据同步出现了错误;也可以发现线程被强行stop后,自动释放了持有的锁。

总结: