线程基础----java对象锁(三)

前言:

      关于对象锁,在网上看了不少文章,但都说了不是很清楚。因而查看资料,发现只有从jvm角度讲对象锁才会容易理解。java

正文:

     java虚拟机的一些运行时数据区会被全部的线程共享,其余数据时各个线程私有的,由于堆和方法区是被全部线程所共享的,java程序须要为两种多线程访问数据进行协调:编程

  • 保存在堆中的实例变量
  • 保存在方法区中的类变量

     程序不须要协调保存在java栈中的局部变量,由于java栈中的数据时属于拥有该栈的线程的私有的。安全

java虚拟机的内部体系结构

jvm

如下文字摘自《深刻java虚拟机》

   在java虚拟机中,每一个对象和类在逻辑上都是和一个监视器相关联的。对于对象来讲,相关联的监视器保护对象的实例变量,对于类来讲,监视器保护类的类变量。若是一个对象没有实例变量。或者一个类没有类变量,相关联的监视器就什么都不监视(补充:变量其实就是数据,加上监视器主要是为了数据安全,一致)。多线程

     为了实现监视器的排他性监视能力,java虚拟机为每一个对象和类都关联一个锁(有时候被称为互斥体(mutex))。一个锁就像一种任什么时候候只容许一个线程“拥有特权”。线程访问实例变量或者类变量就不须要获取锁,可是若是获取了锁,那么他释放这个锁以前,就没有其余线程能够获取一样数据的锁了。(“锁住一个对象”就是获取对象相关联的监视器。)jvm

    类锁实际上用对象锁实现。当java虚拟机转载一个class文件的时候,他会建立一个java.lang.Class类的实例。当锁住一个类的时候,实际上锁住的是那个类的class对象。.net

    一个线程能够运行屡次对同一个对象上锁。对于每个对象来讲,java虚拟机维护一个计数器,记录对象被加了多少次锁。没有被锁的对象计数器为0.但第一个线程第一次获取锁的时候,计数器跳到1,线程每加一次锁一次,计数器就加1.(只有已经拥有了这个对象的锁的线程才能对该对象再次枷锁。在它释放锁以前,其余线程不能对这个对象枷锁)每当线程释放锁一次,计数器就减一。当计数器跳到0的时候,锁就跳到0的时候,锁就被彻底释放了,其余线程才可使用它。线程

   java虚拟机中的一个线程在它到达监视区域开始处的时候请求一个锁。在java中,有两种监视区域:同步语句和同步方法(这些在本章后面会详细描述)。java程序中的每个监视区域都和一个对象引用相关联。当一个线程到达监视区域的第一条指令的时候,线程必须对改引用对象枷锁,不然线程不容许执行其中的代码,一旦它得到了锁,线程就进入了被保护的代码。当线程离开这块代码的时候,无论它是如何离开的,它都会释放相关对象的锁。对象

注意:java编程人员不须要手动枷锁,对象锁是在java虚拟机内部使用的。在java程序中,你只须要编写同步语句,或者同步方法,就能够标示一个监视区域。当java虚拟机运行你的程序的时候,每一次进入一个监视区域的时候,它每次都会自动锁上对象或者类。get

相关文章
相关标签/搜索