java 内在锁(intrinsic lock)或者监视器锁(monitor lock)

在JVM的规范中,有这么一些话:  “在JVM中,每个对象和类在逻辑上都是和一个监视器相关联的,为了实现监视器的排他性监视能力,JVM为每一个对象和类都关联一个锁,锁住了一个对象,就是获得对象相关联的监视器” 

监视器好比一做建筑,它有一个很特别的房间,房间里有一些数据,而且在同一时间只能被一个线程占据,进入这个建筑叫做”进入监视器”,进入建筑中的那个特别的房间叫做”获得监视器”,占据房间叫做”持有监视器”,离开房间叫做”释放监视器”,离开建筑叫做”退出监视器”. 
而一个锁就像一种任何时候只允许一个线程拥有的特权. 一个线程可以允许多次对同一对象上锁.对于每一个对象来说,java虚拟机维护一个计数器,记录对象被加了多少次锁,没被锁的对象的计数器是0,线程每加锁一次,计数器就加1,每释放一次,计数器就减1.当计数器跳到0的时候,锁就被完全释放了. 
java虚拟机中的一个线程在它到达监视区域开始处的时候请求一个锁.JAVA程序中每一个监视区域都和一个对象引用相关联. 

Java提供了synchronized关键字来支持内在锁。Synchronized关键字可以放在方法的前面、对象的前面、类的前面。
1. 同步方法中的锁 当线程调用同步方法时,它自动获得这个方法所在对象的内在锁,并且方法返回时释放锁,如果发生未捕获的异常,也会释放锁。 当调用静态同步方法时,因为静态方法和类相关联,线程获得和这个类关联的Class对象的内在锁。 使用内在锁后,把deposit方法和withdraw方法修改为同步方法,就可以避免线程干扰。 public synchronized void deposit(int amount) { balance = balance + amount; } public synchronized void withdraw(int amount) { balance = balance – amount; } 2. 同步语句 同步语句必须指定提供内在锁的对象,其基本用法如下: synchronized(提供锁的对象){ 临界代码 } 用同步语句修改BankAccount类中的方法如下: public void deposit(int amount) { synchronized (this) { balance = balance + amount; } } public void withdraw(int amount) { synchronized (this) { balance = balance – amount; } } 3. 同步类 把synchronized关键字放在类的前面,这个类中的所有方法都是同步方法。 4. 可重入同步

线程可以获得他已经拥有的锁,运行线程多次获得同一个锁,就是可以重入(reentrant)同步。这种情况通常是同步代码直接或者间接的调用也包含了同步代码的方法,并且两个代码集都使用同一个锁。如果没有可重入同步,那么,同步代码就必须采取很多额外的预防措施避免线程阻塞自己。java java.util.concurrent 包中的  ReentrantLock 即为可重入锁

原文地址:http://blog.163.com/hsh8523@126/blog/static/218935592011214114257822/

    原文作者:java锁
    原文地址: https://blog.csdn.net/fujunsfzh/article/details/53517536
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞