ReentrantReadWriteLock不存在锁升级,只存在锁降级

		private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
	private static ReentrantReadWriteLock.ReadLock rl= readWriteLock.readLock();
	private static ReentrantReadWriteLock.WriteLock wl= readWriteLock.writeLock();

/**
同一个线程获取读锁后再试图获取写锁,这种情况就会出现死锁
试想一下:读锁与读锁之间不存在互斥的问题,读锁跟写锁互斥,互斥就是为了防止读数据期间临界区资源不被
修改,如果获取读锁后,同时其他线程也获取到了读锁,然后该线程试能成功获取写锁,之前的那种保护将没有意义!!
**/
private void testUpgrade(){
        //获取读锁
		rl.lock();
        //获取读锁
		wl.lock();
		wl.unlock();
		rl.unlock();		
		log.info("结束");
	}

/**
下面看下获取读锁后再获取写锁死锁的地方
**/

    public final void acquire(int arg) {
         //tryAcquire失败后会进入acquireQueued方法,acquireQueued里面会不断调用tryAcquire方法试图获取写锁,但本文所说的情况下是不可能获得写锁的
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

        protected final boolean tryAcquire(int acquires) {
            /*
             * Walkthrough:
             * 1. If read count nonzero or write count nonzero
             *    and owner is a different thread, fail.
             * 2. If count would saturate, fail. (This can only
             *    happen if count is already nonzero.)
             * 3. Otherwise, this thread is eligible for lock if
             *    it is either a reentrant acquire or
             *    queue policy allows it. If so, update state
             *    and set owner.
             */
            Thread current = Thread.currentThread();
            int c = getState();
            int w = exclusiveCount(c);
            if (c != 0) {
                // (Note: if c != 0 and w == 0 then shared count != 0)
                //代码会走到这里,但是此时没有任何线程获取到写锁,所以getExclusiveOwnerThread()返回null,current线程为已经获取到试图获取写锁的线程,这里就会直接返回false,接下来就会进入acquireQueued方法
                if (w == 0 || current != getExclusiveOwnerThread())
                    return false;
                if (w + exclusiveCount(acquires) > MAX_COUNT)
                    throw new Error("Maximum lock count exceeded");
                // Reentrant acquire
                setState(c + acquires);
                return true;
            }
            if (writerShouldBlock() ||
                !compareAndSetState(c, c + acquires))
                return false;
            setExclusiveOwnerThread(current);
            return true;
        }

    final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                //获取写锁失败后会根据条件判断是否需要进入睡眠,本文所说的死锁最终会因调用
                //parkAndCheckInterrupt方法放弃cpu资源进入睡眠模式,但是之后没有任何唤醒源,
                //也就是进入了传说中的死锁
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值