Synchronized Integer的问题

you can see that System.identityHashCode(i) changes, so another thread that was waiting outside the synchronized block can now enter it.

but the most important thing,i want to know why another thread has same System.identityHashCode(i) can enter the synchronized block


回答:

当i=10时,两个线程竞争synchronized权限,此时监控器对象是Integer(10),然后张三成功开始执行,并且在最后将i的值改为了Integer(9),但是这时候李四在等待的监控器对象仍然是Integer(10),并不会因为张三的i--而改变,所以当张三离开同步代码块后李四进入了监控器对象为Integer(10)的同步代码块,而张三循环回来后重新尝试进入一个同步代码块,此时它需要获取的监控器对象为Integer(9),所以跟李四不构成竞争关系,两个线程同时进入了监控器对象不同的代码块中,并且读取到的新的i值都是9

深层的原因与synchronized关键字的实现原理有关,多个线程竞争同一个监控器对象,其实是都进入了这个对象关联的monitor的entryList,在这里面就是张三李四都进入了Integer(10)的monitor的entryList,所以就算i被张三改为了Integer(9),也不会改变李四的监控器对象


回答:

  1. 为什么锁没有生效?
    两个线程首次进入时对象锁是Integer(10),所以能够锁住,只有一个线程进入了临界区;做i--时,由于是integer类型,所以先拆箱,之后运算操作。再封装为integer类型,对象不再是原来的对象了,变成了integer(9);张三重进入后,对象锁的是integer(9),而唤醒的李四线程的对象锁是integer(10),对象不同,所以不能内锁住。可以同时进入到临界区。
  2. 为什么有同样的System.identityHashCode(i)
    volatile修饰的i,由于修改了值,所以另外的线程可以感知到。李四线程的对象锁是integer(10),但是由于张三线程修改了值,导致李四的的锁对象还是原来的锁对象,但是里面的值变成了9;是integer(10)的对象,但是里面的值是9,所以,进入到临界区时,得到的是相同的i值。

以上是 Synchronized Integer的问题 的全部内容, 来源链接: utcz.com/p/944188.html

回到顶部