龙空技术网

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

梦幻随风的互联网笔记 95

前言:

目前我们对“java中断程序运行”可能比较看重,大家都需要分析一些“java中断程序运行”的相关资讯。那么小编也在网摘上网罗了一些关于“java中断程序运行””的相关文章,希望大家能喜欢,大家一起来了解一下吧!

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

标签: #java中断程序运行