VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • 简单看看ReentrantLock(3)

InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); return tryAcquire(arg) || doAcquireNanos(arg, nanosTimeout); }
复制代码

 

 

  4.unlock()释放锁

复制代码
public void unlock() {
    sync.release(1);
}

public final boolean release(int arg) {
    //从下面的方法我们可以知道tryRelease只有当state为0的时候才会返回true,也就是当前锁没有被线程持有
    //此时,如果头节点不为null,而且头节点的waitStatus不为初始状态,就唤醒头节点
    if (tryRelease(arg)) {
        Node h = head;
        if (h != null && h.waitStatus != 0)
            unparkSuccessor(h);
        return true;
    }
    return false;
}

protected final boolean tryRelease(int releases) {
    //将AQS中的state减一
    int c = getState() - releases;
    //当前线程如果不是锁的拥有者,却调用了unlock方法,那么就会抛出IllegalMonitorStateException异常
    //在这里就能判断了如果原先的state为0,那么上面的c应该就是负一,就会走到这里来抛错,如果state为1,就会到下面的if(c==0)里面
    //如果state大于1,那么只会到最下面的setState(c)将减一之后的state更新到AQS中
    if (Thread.currentThread() != getExclusiveOwnerThread())
        throw new IllegalMonitorStateException();
    boolean free = false;
    //可重入数字为0,就将当前持有锁的线程设置为null
    if (c == 0) {
        free = true;
        setExclusiveOwnerThread(null);
    }
    //这里不管重入数字是不是0,我们只会将最新的state更新获取
    setState(c);
    return free;
}
复制代码

 

 

六.总结

  我们已经看到了ReentrantLock这个锁的基本功能,其实就是一个独占锁,而且是可重入的,这里的重入指的是一个已经占有了该锁的线程,还可以继续获取该锁!

  下图所示,同时有三个线程去争夺ReentrantLock锁,此时,只有Thread1成功占有锁了,那么其他的两个线程就被丢到AQS阻塞队列中去了(这里是有顺序的,先是Thread2,然后是Thread3);

 

 

  如果这个时候Thread1调用了条件变量1的await方法,那么Thread1就被丢到条件队列1中,并且释放锁,这个时候阻塞队列中就会有一个线程可以获取锁,如果是公平锁,那么就是阻塞队列中最前面的那一个获取锁,此时阻塞队列中只有Thread3了;(如果是非公平锁,那么就是看运气,Thread2和Thread那个先去尝试获取锁那么就获得锁)

--------------以上皆原创,给未来的自己留下一点学习的痕迹!--------

相关教程
关于我们--广告服务--免责声明--本站帮助-友情链接--版权声明--联系我们       黑ICP备07002182号