java 是怎么中断一个线程的,你真的搞懂了吗?interrupt()

java 是怎么中断一个线程的,你真的搞懂了吗?interrupt()

编码文章call10242025-02-16 19:48:1210A+A-

Thread.stop()

当我们使用Thread.stop()方法去停止线程时,这个方法会报错,抛出了
UnsupportedOperationException异常,

它在JDK中已经被声明“过期/作废”的方法,显然它在功能上有缺陷,不建议使用。

interrupt()方法

interrupt()方法的简单理解 interrupt() 方法只是改变中断状态而已,

它不会中断一个正在运行的线程。

这一方法实际完成的是,给受阻塞的线程发出一个中断信号,这样受阻线程就得以退出阻塞的状态。

更确切地说,如果线程被 Object.wait, Thread.join 和 Thread.sleep三种方法之一阻塞,

此时调用该线程的interrupt()方法, 那么该线程将抛出一个 InterruptedException中断异常(该线程必须事先预备好处理此异常), 从而提早地终结被阻塞的状态。


看到这里,可能有人会说 Object.wait, Thread.join 和 Thread.sleep 是什么东西?这里介绍下,仔细看下:

线程中常用的方法 sleep、wait、join

sleep:阻塞当前线程,并不释放锁对象 (当前线程让出cpu资源,不会影响锁,能够在程序的任何地方使用)




wait: 阻塞当前线程,释放锁对象 给其他竞争同一个锁的线程

调用wait方法会使该线程进入等待状态,并且会释放被同步对象的锁

wait、notify以及notifyAll都是Object对象的方法,他们必须在被 synchronized 同步的方法或代码块中调用,否则会报错。

notify操作可以唤醒一个因执行wait而处于阻塞状态的线程,使其进入就绪状态,被唤醒的线程会去尝试着获取对象锁,然后执行wait之后的代码。

如果发出notify操作时,没有线程处于阻塞状态,那么该命令会忽略。

注意执行notify并不会马上释放对象锁,会等到执行完该同步方法或同步代码块后才释放。

notifyAll方法可以唤醒等待队列中等待同一共享资源的“全部”线程从等待状态--->就绪状态,进行锁争夺,类似第3天后面逻辑。

public class WaitDmo {
    private Student s = new Student();
    class T1 extends Thread{
        @Override
        public void run() {
            synchronized (s){
                try {
                    System.out.println("Hello T2");
                    if (s.getName() == null){
                        s.wait();
                    }
                    System.out.println(s);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    class T2 extends Thread{
        @Override
        public void run() {
            synchronized (s){
                try {
                    System.out.println("Hello T1");
                    s.setName("lily");
                    s.notify();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    @Test
    public void test() throws InterruptedException {
        Thread t1 = new T1();
        Thread t2 = new T2();
        t1.start();
        t2.start();
    }
}

当线程一阻塞后,线程二就执行了,
值得注意的是
线程一最后又打印了student对象(name=lily),
是因为线程二唤醒了线程一,
wait和notify搭配使用实现了线程的通信,
对于wait阻塞,也可以直译理解为等待更为贴切。



join: 等待当前线程到死 (可以实现 让多个线程排队执行)


public class MyTread implements Runnable {

    private static volatile int num = 0;

    private String name;

    public MyTread(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        num++;
        System.out.println(name+"num:"+num);
    }
}


   @Test
    public void test() throws InterruptedException {
       
        for (int i = 0; i < 10; i++) {
            Thread t = new Thread(new MyTread("Thread-"+i));
            t.start();
        }
    }
   //这个执行打印的数据肯定不是顺序的
   //可以看到线程并没有顺序执行


    如果我们换成下面这样,就会有线程顺序执行了:
    @Test
    public void test() throws InterruptedException {
        
        for (int i = 0; i <10; i++) {
            Thread t = new Thread(new MyTread("Thread-"+i));
            t.start();
            //就是这里,等待当前线程到死
            t.join();
        }

    }

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4