public E pollLast() {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        return unlinkLast();
    } finally {
        lock.unlock();
    }
 }这段代码中,为什么不直接操作this.lock,而是额外用一个局部final引用????这样写有什么好处么??还是会避免什么问题??

解决方案 »

  1.   

    那就允许别人在 unlinkLast() 调用的过程中修改 this.lock,我们用 lock 这个副本的话,this.lock 的改变对我们这次调用来说没有影响嘛。如果不使用副本的话,lock.lock() 调用完之后的瞬间,有个调用了 setLock(anotherLock) 来改变 this.lock 的值的话,那之后的 this.lock.unlock() 就有问题了,因为释放的不是原来那个 lock 的锁。当然,如果这个类中 this.lock 从来都不会改变的话那就没有什么意思。
      

  2.   

    了解了,那不加final效果也是一样得吧,还有局部变量加了final之后有什么好处呢?
      

  3.   


    public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
        Object oldData[] = elementData;
        int newCapacity = (oldCapacity * 3)/2 + 1;
             if (newCapacity < minCapacity)
    newCapacity = minCapacity;
                // minCapacity is usually close to size, so this is a win:
                elementData = Arrays.copyOf(elementData, newCapacity);
    }
        }
    还有arraylist得数组扩容方法里也有特别诡异得一个写法,Object oldData[] = elementData;   后面oldData没有任何调用,这又是什么意思呢??是跟垃圾回收有关系么?
      

  4.   

    jdk多线程包里的一个双向队列
      

  5.   

    lock(this)的缺点,就是在一个线程锁定某对象之后导致整个对象无法被其他线程访问。通常建议使用不影响其他操作的私有对象来作为locker
      

  6.   

    你说的这个是syn....关键字得对象锁是这样。ReentrantLock锁不是这样的吧,这个写法应该和你说得这个没什么关系。
      

  7.   


    好处有两个
    第一,也就是final的逻辑用意,可以预防后续的代码中程序员对final变量重新赋值。
    第二,用final变量,会赢得少许的性能提高,因为final的变量地址不需要在每次方法调用时再从新计算,而是事先算好的。
      

  8.   


    因为elementData 是transient的。
    所以需要一个引用来保证它不会在方法结束前,由于持久化的原因而挂掉