多线程isInterrupted()与interrupted(),真正的停止线程

本文聚焦Java多线程编程,介绍了currentThread().getName()与this.getName()的区别,还阐述了isInterrupted()与interrupted()用于测试线程是否停止,探讨了真正停止线程的异常法,指出stop()暴力停止的弊端,以及suspend和resume配合使用的问题,最后提及yield放弃CPU资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

currentThread().getName()与this.getName()的区别

public static class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            System.out.println("cur__" + currentThread().getName() + "\nthis___" + this.getName());
        }
    }

    public static void main(String args[]) {
        MyThread myThread = new MyThread();
        Thread a = new Thread(myThread, "A");
        a.start();
    }
输出结果:
cur__A
this___Thread-0
  • currentThread().getName()获取的是当前运行的线程的名字,而this.getName()获取的是MyThread这个类的名字,MyThread继承Thread,从Thread的源码可以看出默认名字为:"Thread-"+num

停止线程:isInterrupted()与interrupted()

isInterrupted()与interrupted()都是测试线程是否停止,并不能真正的停止线程,只是标记作用。

public static class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            for (int i = 0; i < 5000; i++) {
                System.out.println("i = " + i);
            }
        }
    }

    public static void main(String args[]) {
        try {
            MyThread myThread = new MyThread();
            myThread.start();
            Thread.sleep(30); // 注意这段代码,让子线程先跑,让下一段myThread.interrupt()生效
            myThread.interrupt();   // 操作的是子线程,当前线程无法停止
            System.out.println("是否停止"+myThread.isInterrupted()); // 子线程停止状态true
            System.out.println("是否停止"+myThread.interrupted()); //  等同于Thread.interrupted()
            Thread.currentThread().interrupt(); // 停止当前线程main
            System.out.println("是否停止"+myThread.isInterrupted());
            System.out.println("是否停止"+Thread.interrupted());
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("end");
    }

打印结果:

是否停止true
是否停止false

是否停止true
是否停止true
end

注意区分 结果分析:

  • myThread.interrupted() 该方法内部实现为:currentThread().isInterrupted(true);使用等同于Thread.interrupted()。获取的是当前线程main的状态false。
  • myThread.interrupt();// 不是当前线程无法停止 ------和----- Thread.currentThread().interrupt();--------如何理解呢?

源码解析:

myThread.interrupt();
Thread.currentThread().interrupt();

-----------以下为源码部分------------
public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();

        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();           // Just to set the interrupt flag
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }

只有代码所处执行位置为当前的线程才生效。因为例子中的myThread.interrupt();处于main的线程中,无法停止main线程。要停止main线程应该执行:Thread.currentThread().interrupt();

注意:

Thread.interrupted() 停止后会修改状态,恢复线程运行状态
myThread.isInterrupted() 停止后不会修改当前的运行状态

真正的停止线程

异常法

public static class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            try {
                for (int i = 0; i < 5000; i++) {
                    if (interrupted()) { // 获取到停止标记位 
                        System.out.println("停止状态,即将退出");
                        throw new InterruptedException();
                    }
                    System.out.println("i = " + i);
                }
                System.out.println("执行for之后的内容");
            } catch (InterruptedException e) {
                System.out.println("进入catch 方法");
                e.printStackTrace();
            }
        }
    }

    public static void main(String args[]) {
        try {
            MyThread myThread = new MyThread();
            myThread.start();
            Thread.sleep(30);
            myThread.interrupt();// 不是当前线程无法停止
            System.out.println("是否停止" + myThread.isInterrupted());
            System.out.println("是否停止" + Thread.interrupted());
            Thread.currentThread().interrupt();
            System.out.println("是否停止"+Thread.interrupted()); // 重置标记位为false
            System.out.println("是否停止" + Thread.currentThread().isInterrupted());
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("end");
    }

打印结果:

i = 2843
i = 2844
i = 2845
i = 2846
i = 2847
停止状态,即将退出
是否停止false
是否停止false
进入catch 方法
是否停止true
是否停止false
end
java.lang.InterruptedException
	at TestThread$MyThread.run(TestThread.java:10)

Process finished with exit code 0

沉睡中停止

子线程在sleep()状态中调用interrupt()会终止子线程

public static class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            try {
                System.out.println("begin...");
                sleep(10000);
                System.out.println("wakeup");
            } catch (InterruptedException e) {
                System.out.println("进入子线程catch 方法");
                e.printStackTrace();
            }
        }
    }

    public static void main(String args[]) {
        try {
            MyThread myThread = new MyThread();
            myThread.start();
            Thread.sleep(30);   // 先sleep()再interrupt
            myThread.interrupt();// 不是当前线程无法停止
            System.out.println("是否停止" + myThread.isInterrupted());
        } catch (Exception e) {
            System.out.println("进入主线程catch 方法");
            e.printStackTrace();
        }
        System.out.println("end");
    }

打印结果:

begin...
进入子线程catch 方法
是否停止false
end
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at TestThread$MyThread.run(TestThread.java:8)

Process finished with exit code 0

结果分析:

  • 子线程中不管是先sleep()再interrupt()还是先interrupt()再sleep(),都可以中断线程

暴力停止stop()

  • 不建议使用stop()停止线程,因为stop()释放锁会造成数据不一致的问题。

暂停线程suspend和resume

  • 注意:

  • suspend和resume配合synchronize使用的话会造成公共的对象独占,使其他线程无法访问公共同步对象。
  • println()
public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
  • println()源码中也有synchronize同步锁,使用请小心。
  •  

yield

Thread.yield();放弃当前的cpu资源,放弃时间不确定,也有可能刚刚放弃,又立马获取资源。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值