leecyz
2011-10-24 21:28
浏览 239
已采纳

synchronized为什么只能锁对象

synchronized(obj){
//
}

synchronized锁的是对象的引用,存放在栈中,为什么设计时不能锁基本类型,同样存放在栈中,
在内存中占用资源。如果说基本类型超过作用域会释放等原因,可以定义静态变量。

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

6条回答 默认 最新

  • 爱上一条鱼 2011-10-26 10:48
    已采纳

    刚刚查了下
    [quote]
    在java虚拟机中,每个对象和类在逻辑上都是和一个监视器相关联的。
    对于对象来说,相关联的监视器保护对象的实例变量。

    对于类来说,监视器保护类的类变量。

    (如果一个对象没有实例变量,或者一个类没有变量,相关联的监视器就什么也不监视。)
    为了实现监视器的排他性监视能力,java虚拟机为每一个对象和类都关联一个锁。代表任何时候只允许一个线程拥有的特权。线程访问实例变量或者类变量不需锁。

    但是如果线程获取了锁,那么在它释放这个锁之前,就没有其他线程可以获取同样数据的锁了。(锁住一个对象就是获取对象相关联的监视器)

    类锁实际上用对象锁来实现。当虚拟机装载一个class文件的时候,它就会创建一个java.lang.Class类的实例。当锁住一个对象的时候,实际上锁住的是那个类的Class对象。

    一个线程可以多次对同一个对象上锁。对于每一个对象,java虚拟机维护一个加锁计数器,线程每获得一次该对象,计数器就加1,每释放一次,计数器就减 1,当计数器值为0时,锁就被完全释放了。
    [/quote]

    简而言之,就是要对一个对象加锁,需要一个锁指向这个对象,锁有计数器,对这个对象进行监控。。。。。基本类型是不可能被指针指着的。。。。。

    已采纳该答案
    打赏 评论
  • 爱上一条鱼 2011-10-25 12:25

    都说了 是通过对象的引用来锁了。。。。。。。。。基本类型没有引用吧 怎么锁。。。。

    打赏 评论
  • remotejsky 2011-10-25 12:35

    如果基本类型可以被锁,那么它就需要有一个锁对象与之关联(在方法执行的时候会获取或释放),还需要一个wait集合与之关联(wait,notify,notifyall使用)
    那这个基本类型还算是基本类型了吗?并且已经有了基本类型的包装了,这个不是问题了吧我想

    打赏 评论
  • 爱上一条鱼 2011-10-26 10:31

    [quote]
    synchronized锁的是对象的引用,存放在栈中,为什么设计时不能锁基本类型,同样存放在栈中,
    在内存中占用资源。如果说基本类型超过作用域会释放等原因,可以定义静态变量。
    [/quote]

    JAVA中,所有的对象都是继承自Object,Object里面应该封装了锁机制所需要的其他的变量,这样才能使用wait() notify()这类需要锁的函数

    打个比方,你要对某个对象加互斥锁,这个对象必须得封装一个mutex互斥量来计数吧,学习过操作系统的人都有一些了解吧。。。。我猜Object这个类里应该与这种机制

    而基本类型是不可能封装这些锁变量的吧

    打赏 评论
  • 爱上一条鱼 2011-10-26 10:50

    哦 应该这么说 在JAVA里基本类型是不可能被多个引用指着的

    打赏 评论
  • remotejsky 2011-10-26 12:17

    同意asyty的回答。

    在Java中,设计可同步的变量时至少要考虑两点:

    1.需要有一个锁对象与之关联,在synchronized快或方法中的代码,JVM调用的时候,会尝试去获取被Synchronized 的对象或Class的lock。这样才能达到同步。
    2.在执行wait 或notify的时候,需要有一个与之关联的集合来保存这个对象的锁被lock了几次,unlock了几次,满足如可重入锁的需求。这也就和唤醒有关了

    因此在设计同步时,基本类型是很难达到同步需求的。即使可以,那么把基本类型设计的如此笨重,还要基本类型干么呢。这事设计的问题,而不是技术可不可以的问题吧

    打赏 评论

相关推荐 更多相似问题