• java中的interrupt(),InterruptException和wait(),sleep()


        标题中的几个概念大概设计到线程同步以及线程阻塞这两个概念。线程同步,就是同一时刻,只有一个线程能执行指定的代码;另外一个线程阻塞就是当前线程暂时停在某个位置,等待某个条件成立之后再继续往下面执行。

        线程同步就是,是为了控制多线程工作存在的并发造成共享资源竞争的问题。java中可以通过加锁(monitor)的方式来控制,其实就是两个关键字,一个是synchronized,另外一个是lock,关于这两个的区别,请自行google。其中wait方法就必须获取某个对象的monitor之后,才允许执行,否则会跑出monitor status不正确的异常。wait()和join()方法是属于Object的实例方法。wait()方法必须放在同步代码块之内(如下),即是表示获得了某个对象的monitor(锁)之后,才允许执行该对象的wait()方法;执行了wait()方法之后,当前线程会处于阻塞状态,这时候当前线程会释放进来的时候获取的指定对象的monitor(锁),同时让出cpu,不在参与cpu的竞争,等待其他线程执行指定对象的notify()或者notifyAll()方法来将其唤醒,以继续执行下去(被唤醒之后,也要先获取指定对象的锁才会进来,因为同步块进来之前必须是获取了指定对象的monitor,同时,不是从新执行,获得monitor之后,是从之前wait()那里开始继续网下面执行,因为之前在这里阻塞了,cpu相关的寄存在会记住之前阻塞的位置的)。
        
    public class Service {
        public void testMethod(Object lock) {
            try {
                synchronized (lock) {
                    System.out.println("begin wait() ThreadName=" + Thread.currentThread().getName());
                    lock.wait();
                    if (Thread.currentThread().getName().equals("Thread-1")) {
                        Thread.sleep(50000);
                    }
                    System.out.println("end wait() ThreadName=" + Thread.currentThread().getName());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        public void synNotifyMethod(Object lock) {
            synchronized (lock) {
                System.out.println("begin notify() ThreadName=" + Thread.currentThread().getName());
                lock.notifyAll();
                System.out.println("end notify() ThreadName=" + Thread.currentThread().getName());
            }
        }
    }
        至于interrupt()方法和InterruptException异常,是java专门用来处理线程阻塞的。线程阻塞,就表示要等待一段时间。如果需要等待的时间比较长,正常还没结束之前想中断某个线程的阻塞状态怎么办?这就是靠interrupt()方法来解决了。如果因为一些特殊的原因,想提前中断一些阻塞的线程,以让他们提前解除阻塞状态,然后继续执行下去。只需要在其他线程调用指定线程的interrupt()方法即可(interrupt()方法是线程实例方法),这时候原来阻塞的对应的线程就会抛出InterruptException异常,通过catch捕获异常就可以继续往下面执行了。比如线程方法sleep()和Object的实例方法wait(),都会导致当前线程阻塞,这时候就可以通过interrupt()方法来提前退出阻塞状态。
        为什么Interrupt()方法可以提前中断阻塞呢?其实是因为每个线程都会有一个中断状态位,暂且叫做interruptStatus吧。当前执行sleep()和wait()这些方法的时候,当前线程会把该interrruptStatus状态位设置为true,以标识当前线程为阻塞状态。当调用该线程的Interrupt()方法的话,就会重置interruptStatus状态为为false。而sleep()和wait()方法内部会不断地轮询检查InterruptStatus状态值,如果某一时刻变为false的时候,当前线程就会中断阻塞状态,通过抛出InterrupException的方式来中断阻塞状态,然后继续执行下去。
        至于wait()方法和notify()的关系,通过另外一篇文章来讲述吧。





  • 相关阅读:
    <style>的scope属性
    scrollIntoView的使用
    需要学习的内容列表
    react生命周期
    JS对象-不可扩展对象、密封对象、冻结对象
    神策埋点
    Django初识
    MySQL的sql_mode模式说明及设置
    MySQL的逻辑查询语句的执行顺序
    MySQL行(记录)的详细操作
  • 原文地址:https://www.cnblogs.com/ismallboy/p/6785319.html
Copyright © 2020-2023  润新知