并发编程--公平锁和非公平锁
来源:互联网 发布:linux 命令 竖线 编辑:程序博客网 时间:2024/05/29 16:44
在上一篇博客并发编程--互斥锁ReentrantLock中我们简单介绍了一下ReentrantLock,ReentrantLock提供了公平锁和非公平锁的机制,我们已经了解到ReentrantLock提供了一个FIFO线程队列,对于公平锁来说,当锁是可获取时首先让FIFO队列中的线程获取锁,当前线程需要进FIFO队列进行等待;对于非公平锁来说,当锁是可获取时,这个线程可以直接获取锁,不用在FIFO中排队等待。
公平锁实现:
获取锁
final void lock() { acquire(1);//设置state为1 }
//tryAcquire(arg) 尝试获取锁//acquireQueued(addWaiter(Node.EXCLUSIVE), arg)尝试获取锁失败后将线程放到FIFO队列中public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState();//c=0时此时锁可获取 if (c == 0) {//首先判断hasQueuedPredecessors()队列首的线程是否是当前线程,不是则不作操作最后返回false if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } }//即使c不等于0,需要判断当前获取锁的线程是否是当前线程 else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; } }以上代码的实现机制:当前线程是否是FIFO队列的第一个线程,如果不是当前线程则进FIFO队列,实现了公平锁,如果当前线程是FIFO队列中的第一个线程则获取锁并运行。
非公平锁:
final void lock() {//如果当前锁是可获取的,则当前线程直接获取锁不用进FIFO排队获取锁if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());else//不然,排队获取锁acquire(1);}以上代码的实现机制:如果当前锁是可获取的则直接获取锁,不用排队,不然则需要进FIFO队列排队获取锁。
简单来说Reentrant的实现就是依靠公平锁和非公平锁实现的。
非公平锁源码:
//非公平锁 static final class NonfairSync extends Sync { private static final long serialVersionUID = 7316153563782823691L; final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } }公平锁源码:
//公平锁 static final class FairSync extends Sync { private static final long serialVersionUID = -3000897897090466540L; final void lock() { acquire(1); } /** * Fair version of tryAcquire. Don't grant access unless * recursive call or no waiters or is first. */ protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; } }公平锁和非公平锁的父类是同步锁Sync,源码如下,其实FIFO和volatile变量都是在AbstractQueuedSynchronizer中实现的,AbstractQueuedSynchronizer是同步包中实现锁机制最重要的类。
abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = -5179523762034025860L; abstract void lock(); final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; } protected final boolean tryRelease(int releases) { int c = getState() - releases; if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; if (c == 0) { free = true; setExclusiveOwnerThread(null); } setState(c); return free; } protected final boolean isHeldExclusively() { // While we must in general read state before owner, // we don't need to do so to check if current thread is owner return getExclusiveOwnerThread() == Thread.currentThread(); } final ConditionObject newCondition() { return new ConditionObject(); } // Methods relayed from outer class final Thread getOwner() { return getState() == 0 ? null : getExclusiveOwnerThread(); } final int getHoldCount() { return isHeldExclusively() ? getState() : 0; } final boolean isLocked() { return getState() != 0; } /** * Reconstitutes the instance from a stream (that is, deserializes it). */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); setState(0); // reset to unlocked state } }
2 0
- 并发编程--公平锁和非公平锁
- java并发库 Lock 公平锁和非公平锁
- java并发库 Lock 公平锁和非公平锁
- java并发编程--AbstractQueuedSynchronizer公平锁和非公平锁分析(三)
- 公平锁和非公平锁
- 公平锁和非公平锁
- 公平锁和非公平锁
- 非公平锁 和 公平锁
- 公平锁 非公平锁
- 重入锁和自旋锁(公平锁及非公平锁)
- java多线程的公平锁和非公平锁
- java之ReentrantLock公平锁和非公平锁
- Java中的公平锁和非公平锁实现详解
- Java中ReentrantLock的公平锁和非公平锁
- ReentrantLock的公平锁和非公平锁
- 公平锁和非公平锁(demo)
- Java多线程编程4--Lock的使用--公平锁和非公平锁
- 公平锁与非公平锁
- Java实现https访问
- 欢迎使用CSDN-markdown编辑器
- 数据标准化/归一化方法(Data Normalization Method )
- 方法
- Java实现Md5加密
- 并发编程--公平锁和非公平锁
- 提供一个linux串口程序
- 用户权限设计(一)-数据库设计
- Opencv学习---霍夫变换
- 套接字模式
- 卸载win10 自带应用
- 栈
- 前台获取后台返回的图片并显示
- 宜信大数据创新中心2017实习生面试(三轮)