Java虚拟机中的线程控制

  1.对多线程的支持是Java语言的一大优势,Java对线程的控制主要集中在对线程的同步和协作上,Java使用的同步机制是监视器

  2.Java中的监视器支持两种线程,互斥和协作

     互斥通过对象锁实现,目的是保证不能同时有多个线程操作共享数据,对共享数据的操作语句放在监视器的监视区域中,线程只有获得对象锁才能够执行监视区域的操作。

     同步是共享数据的状态不满足线程正确执行的条件,线程需要执行Object的wait()方法,进入到对象的等待池中,直到另外一个线程修改共享数据的状态,使它满足等待线程的需求时,将等待线程唤醒,但是,如果唤醒线程没有执行完毕监视区域,或者没有调用wait()方法,它将继续执行,继续执行的过程中可能会再次修改共享数据的状态,因此,等待线程在再次进入监视区域之后要重新判断共享数据的状态是否符合要求。

     内存运行数据区的堆区和方法区是所有线程所共享的,因此对这些数据的访问需要进行线程的同步管理,对于局部变量,每个线程拥有自己的Java方法栈,其中保存了每一个方法的局部变量,局部变量的生命周期就是方法的生命周期,每个线程都有自己的局部变量,这些变量不是线程所共享的,对这些变量的操作无需进行互斥操作。

 

     2.1 JVM通过对象锁实现互斥,保证多个线程在同一个共享数据上独立而互不干扰地工作

     2.2 协作通过Object类的wait和notify方法实现,允许多个线程为同一个目标而共同奋斗

     2.3 监视器会关联一些代码:这些代码是最小的,不可分割的代码块,在同一个监视器中,监视区域只能被一个线程执行,当一个线程到达监视区域的开始处,线程就进入到了监视器中,如果此时没有其他线程在入口处等待,并且监视区域中没有任何线程正在执行,这个线程就可以获得监视器,执行监视区域的代码,当监视区域的所有代码执行结束后,线程就会退出监视器,如果线程在执行过程中因为某种原因进入阻塞状态,则称线程为释放监视器

     2.4 互斥操作时只在多线程环境中,只能够有一个线程执行监视区域,互斥帮助线程在访问共享数据时不被其他线程干扰

     2.5 协作保证线程之间相互协调,共同完成相同的目标

           在如下情况中需要进行线程协作

             如果某个线程需要共享数据处于某种状态时才能够正确执行,而当前共享数据没有处于这种状态,需要其他线程的执行才能够使线程处于这种状态,这是,线程要执行wait()方法,释放对象锁,释放监视器,进入到等待区中,其他线程获得对象锁,获得监视器后,执行监视区域的代码,更改共享数据的状态,当共享数据的状态符合等待线程的要求时,线程会执行notify()方法,将等待线程唤醒,但是,执行唤醒操作之后,当前线程会继续执行,直至当前线程执行监视区域结束或者执行wait()方法

    2.6 wait()方法必须置于一个循环体中,因为等待线程获得监视器后仍要进行判断,判断共享数据的状态是否满足自己的需求,因为唤醒线程在执行(只有共享数据的状态满足等待线程的需要时,才会执行唤醒操作)唤醒操作后继续执行,在这个过程中可能会改变共享数据的状态,而且,唤醒线程结束后,可能会有其他线程的优先级更高,抢在等待线程执行之前占用CPU,这些线程也有可能改变共享数据的状态,因此在等待线程重新执行之前,一定要判断共享数据的状态是否满足要求,如果不满足,依旧要释放监视器,进入等待状态中。

  3. 对象锁

       Java程序需要为两种数据进行多线程的访问协调

        (1)保存在堆中的实例变量

        (2)保存在方法区中的类变量

       3.1 在JVM中,每一个对象和类在逻辑上都和一个监视器相关联,对于对象而言,相关联的监视器保护对象的实例变量,对于类而言,监视器保护类变量,如果一个对象没有实例变量,或者一个类没有类变量,则监视器什么都不监视

        3.2 JVM为每一个对象和类都关联一个锁,锁的价值在于任何时候只能够有一个线程拥有访问实例变量或者类变量的特权,如果一个线程获得锁,在它释放锁之前,没有任何其他的线程能够访问共享数据。

        3.3 每一个类也和一个对象锁关联,是代表类型数据的java.lang.Class类型的对象的锁。

阅读更多
个人分类: Java
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭