1. @SuppressWarnings("restriction")
  2. public class ReentrantReadWriteLock1 implements ReadWriteLock, java.io.Serializable {
  3. private static final long serialVersionUID = -6992448646407690164L;
  4. private final ReentrantReadWriteLock1.ReadLock readerLock;
  5. private final ReentrantReadWriteLock1.WriteLock writerLock;
  6. final Sync sync;
  7.  
  8. public ReentrantReadWriteLock1() {
  9. this(false);
  10. }
  11.  
  12. public ReentrantReadWriteLock1(boolean fair) {
  13. sync = fair ? new FairSync() : new NonfairSync();
  14. readerLock = new ReadLock(this);//写锁和读锁,公用同一个Sync,也就是同一个AQS队列,
  15. writerLock = new WriteLock(this);
  16. }
  17.  
  18. public ReentrantReadWriteLock1.WriteLock writeLock() {
  19. return writerLock;
  20. }
  21.  
  22. public ReentrantReadWriteLock1.ReadLock readLock() {
  23. return readerLock;
  24. }
  25.  
  26. abstract static class Sync extends AbstractQueuedSynchronizer1 {//ReentrantLock有自己的Sync,都继承AQS类,
  27. private static final long serialVersionUID = 6317671515068378041L;
  28.  
  29. static final int SHARED_SHIFT = ;
  30. static final int SHARED_UNIT = ( << SHARED_SHIFT);// 2^16
  31. static final int MAX_COUNT = ( << SHARED_SHIFT) - ;// 2^16-1
  32. static final int EXCLUSIVE_MASK = ( << SHARED_SHIFT) - ;// 2^16-1
  33.  
  34. static int sharedCount(int c) {//小于2^16=0,等于2^16=1,大于2^16>1,共享锁最大共享线程数=2^16-1,
  35. return c >>> SHARED_SHIFT;// 右移16位,
  36. }
  37.  
  38. static int exclusiveCount(int c) {
  39. return c & EXCLUSIVE_MASK;// 去掉前面16位,
  40. }
  41.  
  42. static final class HoldCounter {
  43. int count = ;
  44. final long tid = getThreadId(Thread.currentThread());
  45. }
  46.  
  47. static final class ThreadLocalHoldCounter extends ThreadLocal<HoldCounter> {
  48. public HoldCounter initialValue() {
  49. return new HoldCounter();//ThreadLocalHoldCounter作为key,new HoldCounter()作为value,
  50. }
  51. }
  52.  
  53. //当前线程持有的可重入读锁的数量。构造函数中初始化。每当线程的读计数下降到0时删除。
  54. private transient ThreadLocalHoldCounter readHolds;//只有一个
  55.  
  56. private transient HoldCounter cachedHoldCounter;//多个
  57.  
  58. private transient Thread firstReader = null;
  59. private transient int firstReaderHoldCount;
  60.  
  61. Sync() {
  62. readHolds = new ThreadLocalHoldCounter();//只有一个
  63. setState(getState());
  64. }
  65.  
  66. abstract boolean readerShouldBlock();
  67. abstract boolean writerShouldBlock();
  68.  
  69. protected final boolean tryRelease(int releases) {//写锁释放
  70. if (!isHeldExclusively())
  71. throw new IllegalMonitorStateException();
  72. int nextc = getState() - releases;// 状态变量的值减1
  73. boolean free = exclusiveCount(nextc) == ;//写锁=0
  74. if (free)//getState()-releases == 0
  75. setExclusiveOwnerThread(null);
  76. setState(nextc);
  77. return free;
  78. }
  79.  
  80. protected final boolean tryAcquire(int acquires) {//WriteLock获取锁,多线程访问
  81. Thread current = Thread.currentThread();
  82. int c = getState();
  83. int w = exclusiveCount(c);//w=0则C=2^16,w!=0则C<2^16,写锁被获取的次数
  84.  
  85. if (c != ) {//锁里面有线程了重入锁,写锁只要看见state里面有线程就去排队(可能里面有读锁或者写锁),
  86.  
  87. // c!=0,w=0:说明C=2^16的整数倍,说明有读线程获取了锁,
  88. if (w == || current != getExclusiveOwnerThread()) // c!=0,w=0,说明有读锁进去,写锁不进去,其它线程获取了互斥锁(写锁)
  89. return false;//获取锁失败去排队
  90.  
  91. /*单线程进来,线程安全的。 */
  92.  
  93. //w!=0&&current=OwnerThread,MAX_COUNT=2^16-1,就去加值,
  94. if (w + exclusiveCount(acquires) > MAX_COUNT)
  95. throw new Error("Maximum lock count exceeded");
  96. //w!=0&&current=OwnerThread,MAX_COUNT=2^16-1,就去加值,
  97. setState(c + acquires);//acquires每次都是从1开始的,C从0开始,所以c,w,acquires不可能大于2^16。
  98. return true;
  99. }
  100. //c=0,锁里面没有线程,就要去抢锁。
  101. //writerShouldBlock:非公平返回false,就去获取锁。
  102. //writerShouldBlock:公平,返回true排队,返回false,就去获取锁。
  103. //获取state成功设置owenerThread=自己,不去排队,获取state失败,去排队。
  104. if (writerShouldBlock() || !compareAndSetState(c, c + acquires))
  105. return false;
  106.  
  107. /*单线程进来,线程安全的。
  108. compareAndSetState(c, c+acquires)可以作为一把锁,synchronized,
  109. 别的线程要想进到compareAndSetState包裹的代码里面去,必须重新获取新的c=c+acquires,但是进去if(c!=0)里面去了。
  110. */
  111.  
  112. setExclusiveOwnerThread(current);//获得锁。
  113. return true;
  114. }
  115.  
  116. protected final boolean tryReleaseShared(int unused) {// 读锁释放(共享锁),unused没有使用
  117. Thread current = Thread.currentThread();
  118. if (firstReader == current) {
  119. // 如果第一个读者(读线程)是当前线程
  120. // 就把它重入的次数减1
  121. // 如果减到0了就把第一个读者置为空
  122. if (firstReaderHoldCount == )
  123. firstReader = null;
  124. else
  125. firstReaderHoldCount--;
  126. } else {
  127. // 如果第一个读者不是当前线程,一样地,把它重入的次数减1
  128. HoldCounter rh = cachedHoldCounter;//最后获取读锁的HoldCounter
  129. if (rh == null || rh.tid != getThreadId(current))
  130. rh = readHolds.get();//get方法没有时候,就回去创建,有就返回。返回当前线程threadLcoalMap里面的那行记录
  131. int count = rh.count;
  132. if (count <= ) {
  133. readHolds.remove();
  134. if (count <= )
  135. throw unmatchedUnlockException();
  136. }
  137. --rh.count;
  138. }
  139. for (;;) {// 共享锁获取的次数减1,如果减为0了说明完全释放了,才返回true
  140. int c = getState();
  141. int nextc = c - SHARED_UNIT;//减去65536
  142. if (compareAndSetState(c, nextc))
  143. return nextc == ;//读锁完全释放了,
  144. }
  145. }
  146.  
  147. private IllegalMonitorStateException unmatchedUnlockException() {
  148. return new IllegalMonitorStateException("attempt to unlock read lock, not locked by current thread");
  149. }
  150.  
  151. //读锁每次进来加65536,写锁每次进来加1,
  152. protected final int tryAcquireShared(int unused) {//ReadLock获取锁,走这个方法,并发问题,unused没有使用
  153. // 在读写锁模式下,高16位存储的是共享锁(读锁)被获取的次数,低16位存储的是互斥锁(写锁)被获取的次数
  154. Thread current = Thread.currentThread();
  155. int c = getState();//state在AQS类里面,读锁写锁,公用一个Sync AQS state,写锁只能一个进去,另一个写锁进不去,读锁也进不去,
  156. if (exclusiveCount(c) != /*去掉前面16位,*/ && getExclusiveOwnerThread() != current)//state!=0,并且 当前线程没有获取锁。如果写线程获取了锁,state+1就返回-1去排队。
  157. return -;
  158. int r = sharedCount(c);//右移16位, 读锁被获取的次数
  159. //多线程可以进来
  160. if (!readerShouldBlock()/* AQS队列第一个节点写线程跳过,没有第一个节点或者第一个是读线程就进去 */ && r < MAX_COUNT
  161. && compareAndSetState(c, c + SHARED_UNIT)/* c每次增加65536 */) {
  162. //可以多线程进来,AQS队列没有节点 并且 c是2^16的整数倍=0就是没有写锁,第一个线程进来后只要后面的线程重新获取c就可以进来,
  163.  
  164. // 注意下面对firstReader的处理:firstReader是不会放到readHolds里的
  165. // 这样,在读锁只有一个的情况下,就避免了查找readHolds。
  166. if (r == ) {//r=0,c<2^16,没有读锁
  167. firstReader = current;//获取读锁的线程,Thread
  168. firstReaderHoldCount = ;
  169. } else if (firstReader == current) {//重入锁
  170. firstReaderHoldCount++;
  171. } else {
  172. //先查缓存
  173. HoldCounter rh = cachedHoldCounter;//HoldCounter,缓存前一个线程的HoldCounter(线程id和获取锁次数)
  174. if (rh == null || rh.tid != getThreadId(current))
  175. //ThreadLocal里面get,ThreadLocalHoldCounter。
  176. //当前线程的threadLocals属性的threadLocalMap里面加了一行记录(key=readHolds[ThreadLocalHoldCounter],value=cachedHoldCounter[HoldCounter]),
  177. //其他线程也会在他的threadLocals的threadLocalMap里面加一行记录(key=readHolds[ThreadLocalHoldCounter],value=cachedHoldCounter[HoldCounter]),
  178. //每个线程里面只有一行记录,ThreadLocal是公用的,因为只有一个ThreadLocal,value放的是线程的id和计数器。就这样线程就获取了锁,
  179. cachedHoldCounter = rh = readHolds.get();
  180. else if (rh.count == )//当前线程就是上一次线程,就修改thradLocals
  181. readHolds.set(rh);
  182. rh.count++;//多个读,只有一个firstReader,其余的都是在线程里面的threadLocals里面加了一行记录,重入的次数加1(初始次数为0)
  183. }
  184. return ;//获取了锁
  185. }
  186. //有人在排队
  187. return fullTryAcquireShared(current);
  188. }
  189.  
  190. //在tryAcquireShared中经行了一次快速锁获取,但是由于CAS只能允许一个线程获取锁成功,且读锁是共享的,
  191. //可能存在其他仍然可以获取锁的线程,所以在函数末尾调用函数fullTryAcquireShared来进行死循环的获取锁,
  192. final int fullTryAcquireShared(Thread current) {//获取读锁
  193. HoldCounter rh = null;
  194. for (;;) {//死循环
  195. int c = getState();
  196. if (exclusiveCount(c) != ) {//去掉前面16位!= 0
  197. if (getExclusiveOwnerThread() != current)//相等,就是先获取写锁在获取读锁,
  198. return -;//排队
  199. // 否则,我们持有独占锁;在这里阻塞将导致死锁。
  200. } else if (readerShouldBlock()) {//去掉前面16位= 0,并且AQS队列有第一个节点是写锁不是读锁,
  201. // 确保我们没有重新获取读锁
  202. if (firstReader == current) {
  203. // assert firstReaderHoldCount > 0;
  204. } else {
  205. if (rh == null) {
  206. rh = cachedHoldCounter;
  207. if (rh == null || rh.tid != getThreadId(current)) {
  208. rh = readHolds.get();//设置当前线程的threadLocals,key还是readHolds同一个ThreadLocal,
  209. if (rh.count == )//!=0,就说明这个线程之前已经获取一次锁成功了,
  210. readHolds.remove();//从当前线程threadLocals中移除这行记录,
  211. }
  212. }
  213. if (rh.count == )
  214. return -;//排队,
  215. }
  216. }
  217.  
  218. //AQS没有节点,有第一个节点,第一个节点只能是读节点,就去设置threadLcoalMap并且获取锁,
  219. if (sharedCount(c) == MAX_COUNT)
  220. throw new Error("Maximum lock count exceeded");
  221. if (compareAndSetState(c, c + SHARED_UNIT)) {
  222. if (sharedCount(c) == ) {//=0,就说明没有读线程,
  223. firstReader = current;
  224. firstReaderHoldCount = ;
  225. } else if (firstReader == current) {
  226. firstReaderHoldCount++;
  227. } else {
  228. if (rh == null)
  229. rh = cachedHoldCounter;
  230. if (rh == null || rh.tid != getThreadId(current))
  231. rh = readHolds.get();
  232. else if (rh.count == )
  233. readHolds.set(rh);
  234. rh.count++;
  235. cachedHoldCounter = rh; // cache for release
  236. }
  237. return ;//获取了锁
  238. }
  239. }
  240. }
  241.  
  242. final boolean tryWriteLock() {
  243. Thread current = Thread.currentThread();
  244. int c = getState();
  245. if (c != ) {
  246. int w = exclusiveCount(c);
  247. if (w == || current != getExclusiveOwnerThread())
  248. return false;
  249. if (w == MAX_COUNT)
  250. throw new Error("Maximum lock count exceeded");
  251. }
  252. //c=0
  253. if (!compareAndSetState(c, c + ))
  254. return false;
  255. setExclusiveOwnerThread(current);
  256. return true;
  257. }
  258.  
  259. final boolean tryReadLock() {
  260. Thread current = Thread.currentThread();
  261. for (;;) {
  262. int c = getState();
  263. if (exclusiveCount(c) != && getExclusiveOwnerThread() != current)
  264. return false;
  265. int r = sharedCount(c);
  266. if (r == MAX_COUNT)
  267. throw new Error("Maximum lock count exceeded");
  268. if (compareAndSetState(c, c + SHARED_UNIT)) {
  269. if (r == ) {
  270. firstReader = current;
  271. firstReaderHoldCount = ;
  272. } else if (firstReader == current) {
  273. firstReaderHoldCount++;
  274. } else {
  275. HoldCounter rh = cachedHoldCounter;
  276. if (rh == null || rh.tid != getThreadId(current))
  277. cachedHoldCounter = rh = readHolds.get();
  278. else if (rh.count == )
  279. readHolds.set(rh);
  280. rh.count++;
  281. }
  282. return true;
  283. }
  284. }
  285. }
  286.  
  287. protected final boolean isHeldExclusively() {
  288. return getExclusiveOwnerThread() == Thread.currentThread();
  289. }
  290.  
  291. final ConditionObject newCondition() {
  292. return new ConditionObject();
  293. }
  294.  
  295. final Thread getOwner() {
  296. return ((exclusiveCount(getState()) == ) ? null : getExclusiveOwnerThread());
  297. }
  298.  
  299. final int getReadLockCount() {
  300. return sharedCount(getState());
  301. }
  302.  
  303. final boolean isWriteLocked() {
  304. return exclusiveCount(getState()) != ;
  305. }
  306.  
  307. final int getWriteHoldCount() {
  308. return isHeldExclusively() ? exclusiveCount(getState()) : ;
  309. }
  310.  
  311. final int getReadHoldCount() {
  312. if (getReadLockCount() == )
  313. return ;
  314.  
  315. Thread current = Thread.currentThread();
  316. if (firstReader == current)
  317. return firstReaderHoldCount;
  318.  
  319. HoldCounter rh = cachedHoldCounter;
  320. if (rh != null && rh.tid == getThreadId(current))
  321. return rh.count;
  322.  
  323. int count = readHolds.get().count;
  324. if (count == )
  325. readHolds.remove();
  326. return count;
  327. }
  328.  
  329. private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
  330. s.defaultReadObject();
  331. readHolds = new ThreadLocalHoldCounter();
  332. setState(); // reset to unlocked state
  333. }
  334.  
  335. final int getCount() {
  336. return getState();
  337. }
  338. }
  339.  
  340. static final class NonfairSync extends Sync {
  341. private static final long serialVersionUID = -8159625535654395037L;
  342.  
  343. final boolean writerShouldBlock() {//false获取锁。
  344. return false;
  345. }
  346.  
  347. final boolean readerShouldBlock() {// 非公平读是否要阻塞,true排队,false获取锁。
  348. return apparentlyFirstQueuedIsExclusive();//AQS队列有第一个节点是写锁不是读锁,
  349. }
  350. }
  351.  
  352. static final class FairSync extends Sync {
  353. private static final long serialVersionUID = -2274990926593161451L;
  354.  
  355. final boolean writerShouldBlock() {// 公平写是否要阻塞,true排队,false获取锁。
  356. return hasQueuedPredecessors();
  357. }
  358.  
  359. final boolean readerShouldBlock() {// 公平读是否要阻塞,true排队,false获取锁。
  360. return hasQueuedPredecessors();
  361. }
  362. }
  363.  
  364. public static class ReadLock implements Lock, java.io.Serializable {
  365. private static final long serialVersionUID = -5992448646407690164L;
  366. private final Sync sync;
  367.  
  368. protected ReadLock(ReentrantReadWriteLock1 lock) {// 外部类this
  369. sync = lock.sync;
  370. }
  371.  
  372. public void lock() {//获取读锁,获取的是共享锁,调用sync.acquireShared(AQS的方法),写锁调用sync.acquire(AQS的方法)
  373. try {
  374. sync.acquireShared();
  375. } catch (InterruptedException e) {
  376. e.printStackTrace();
  377. }
  378. }
  379.  
  380. public void lockInterruptibly() throws InterruptedException {
  381. sync.acquireSharedInterruptibly();
  382. }
  383.  
  384. public boolean tryLock() {
  385. return sync.tryReadLock();
  386. }
  387.  
  388. public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
  389. return sync.tryAcquireSharedNanos(, unit.toNanos(timeout));
  390. }
  391.  
  392. public void unlock() {
  393. sync.releaseShared();
  394. }
  395.  
  396. public Condition newCondition() {
  397. throw new UnsupportedOperationException();
  398. }
  399.  
  400. public String toString() {
  401. int r = sync.getReadLockCount();
  402. return super.toString() + "[Read locks = " + r + "]";
  403. }
  404. }
  405.  
  406. public static class WriteLock implements Lock, java.io.Serializable {
  407. private static final long serialVersionUID = -4992448646407690164L;
  408. private final Sync sync;
  409.  
  410. protected WriteLock(ReentrantReadWriteLock1 lock) {
  411. sync = lock.sync;
  412. }
  413.  
  414. public void lock() {//获取写锁,写锁的获取逻辑和ReentrantLock一样,失败的加入AQS队列,
  415. try {//读锁调用sync.acquireShared(AQS的方法),写锁调用sync.acquire(AQS的方法)
  416. sync.acquire();//尝试获取锁,获取失败就在AQS阻塞排队
  417. } catch (InterruptedException e) {
  418. e.printStackTrace();
  419. }
  420. }
  421.  
  422. public void lockInterruptibly() throws InterruptedException {
  423. sync.acquireInterruptibly();
  424. }
  425.  
  426. public boolean tryLock() {
  427. return sync.tryWriteLock();//获取读锁,不在AQS类里面,在本Sync类里面,
  428. }
  429.  
  430. public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
  431. return sync.tryAcquireNanos(, unit.toNanos(timeout));
  432. }
  433.  
  434. public void unlock() {
  435. sync.release();//写锁释放,线程安全,唤醒AQS头结点,
  436. }
  437.  
  438. public Condition newCondition() {
  439. return sync.newCondition();
  440. }
  441.  
  442. public String toString() {
  443. Thread o = sync.getOwner();
  444. return super.toString() + ((o == null) ? "[Unlocked]" : "[Locked by thread " + o.getName() + "]");
  445. }
  446.  
  447. public boolean isHeldByCurrentThread() {
  448. return sync.isHeldExclusively();
  449. }
  450.  
  451. public int getHoldCount() {
  452. return sync.getWriteHoldCount();
  453. }
  454. }
  455.  
  456. public final boolean isFair() {
  457. return sync instanceof FairSync;
  458. }
  459.  
  460. protected Thread getOwner() {
  461. return sync.getOwner();
  462. }
  463.  
  464. public int getReadLockCount() {
  465. return sync.getReadLockCount();
  466. }
  467.  
  468. public boolean isWriteLocked() {
  469. return sync.isWriteLocked();
  470. }
  471.  
  472. public boolean isWriteLockedByCurrentThread() {
  473. return sync.isHeldExclusively();
  474. }
  475.  
  476. public int getWriteHoldCount() {
  477. return sync.getWriteHoldCount();
  478. }
  479.  
  480. public int getReadHoldCount() {
  481. return sync.getReadHoldCount();
  482. }
  483.  
  484. protected Collection<Thread> getQueuedWriterThreads() {
  485. return sync.getExclusiveQueuedThreads();
  486. }
  487.  
  488. protected Collection<Thread> getQueuedReaderThreads() {
  489. return sync.getSharedQueuedThreads();
  490. }
  491.  
  492. public final boolean hasQueuedThreads() {
  493. return sync.hasQueuedThreads();
  494. }
  495.  
  496. public final boolean hasQueuedThread(Thread thread) {
  497. return sync.isQueued(thread);
  498. }
  499.  
  500. public final int getQueueLength() {
  501. return sync.getQueueLength();
  502. }
  503.  
  504. protected Collection<Thread> getQueuedThreads() {
  505. return sync.getQueuedThreads();
  506. }
  507.  
  508. public boolean hasWaiters(Condition condition) {
  509. if (condition == null)
  510. throw new NullPointerException();
  511. if (!(condition instanceof AbstractQueuedSynchronizer1.ConditionObject))
  512. throw new IllegalArgumentException("not owner");
  513. return sync.hasWaiters((AbstractQueuedSynchronizer1.ConditionObject) condition);
  514. }
  515.  
  516. public int getWaitQueueLength(Condition condition) {
  517. if (condition == null)
  518. throw new NullPointerException();
  519. if (!(condition instanceof AbstractQueuedSynchronizer1.ConditionObject))
  520. throw new IllegalArgumentException("not owner");
  521. return sync.getWaitQueueLength((AbstractQueuedSynchronizer1.ConditionObject) condition);
  522. }
  523.  
  524. protected Collection<Thread> getWaitingThreads(Condition condition) {
  525. if (condition == null)
  526. throw new NullPointerException();
  527. if (!(condition instanceof AbstractQueuedSynchronizer1.ConditionObject))
  528. throw new IllegalArgumentException("not owner");
  529. return sync.getWaitingThreads((AbstractQueuedSynchronizer1.ConditionObject) condition);
  530. }
  531.  
  532. public String toString() {
  533. int c = sync.getCount();
  534. int w = Sync.exclusiveCount(c);
  535. int r = Sync.sharedCount(c);
  536.  
  537. return super.toString() + "[Write locks = " + w + ", Read locks = " + r + "]";
  538. }
  539.  
  540. // Thread Id可以被重写
  541. static final long getThreadId(Thread thread) {
  542. return UNSAFE.getLongVolatile(thread, TID_OFFSET);
  543. }
  544.  
  545. private static final sun.misc.Unsafe UNSAFE;
  546. private static final long TID_OFFSET;
  547. static {
  548. try {
  549. UNSAFE = java.security.AccessController
  550. .doPrivileged(new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
  551. public sun.misc.Unsafe run() throws Exception {
  552. Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
  553. for (java.lang.reflect.Field f : k.getDeclaredFields()) {
  554. f.setAccessible(true);
  555. Object x = f.get(null);
  556. if (k.isInstance(x))
  557. return k.cast(x);
  558. }
  559. throw new NoSuchFieldError("the Unsafe");
  560. }
  561. });
  562. Class<?> tk = Thread.class;
  563. TID_OFFSET = UNSAFE.objectFieldOffset(tk.getDeclaredField("tid"));
  564. } catch (Exception e) {
  565. throw new Error(e);
  566. }
  567. }
  568.  
  569. }

ReentrantReadWriteLock源码的更多相关文章

  1. 【Java并发编程】16、ReentrantReadWriteLock源码分析

    一.前言 在分析了锁框架的其他类之后,下面进入锁框架中最后一个类ReentrantReadWriteLock的分析,它表示可重入读写锁,ReentrantReadWriteLock中包含了两种锁,读锁 ...

  2. ReentrantReadWriteLock 源码分析

    ReentrantReadWriteLock  源码分析: 1:数据结构: 成员变量: private final ReentrantReadWriteLock.ReadLock readerLock ...

  3. Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析

    Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...

  4. 深入浅出ReentrantReadWriteLock源码解析

    读写锁实现逻辑相对比较复杂,但是却是一个经常使用到的功能,希望将我对ReentrantReadWriteLock的源码的理解记录下来,可以对大家有帮助 前提条件 在理解ReentrantReadWri ...

  5. Java并发编程笔记之读写锁 ReentrantReadWriteLock 源码分析

    我们知道在解决线程安全问题上使用 ReentrantLock 就可以,但是 ReentrantLock 是独占锁,同时只有一个线程可以获取该锁,而实际情况下会有写少读多的场景,显然 Reentrant ...

  6. ReentrantReadWriteLock源码分析(一)

    此处源码分析,主要是基于读锁,非公平机制,JDK1.8. 问题: 1.ReentrantReadWriteLock是如何创建读锁与写锁? 2.读锁与写锁的区别是什么? 3.锁的重入次数与获取锁的线程数 ...

  7. Java显式锁学习总结之五:ReentrantReadWriteLock源码分析

    概述 我们在介绍AbstractQueuedSynchronizer的时候介绍过,AQS支持独占式同步状态获取/释放.共享式同步状态获取/释放两种模式,对应的典型应用分别是ReentrantLock和 ...

  8. Java多线程——ReentrantReadWriteLock源码阅读

    之前讲了<AQS源码阅读>和<ReentrantLock源码阅读>,本次将延续阅读下ReentrantReadWriteLock,建议没看过之前两篇文章的,先大概了解下,有些内 ...

  9. 死磕 java同步系列之ReentrantReadWriteLock源码解析

    问题 (1)读写锁是什么? (2)读写锁具有哪些特性? (3)ReentrantReadWriteLock是怎么实现读写锁的? (4)如何使用ReentrantReadWriteLock实现高效安全的 ...

  10. ReentrantReadWriteLock源码分析笔记

    ReentrantReadWriteLock包含两把锁,一是读锁ReadLock, 此乃共享锁, 一是写锁WriteLock, 此乃排它锁. 这两把锁都是基于AQS来实现的. 下面通过源码来看看Ree ...

随机推荐

  1. 【原创】闲来无事,用Winform写了个简易浏览器

    核心是利用了winform自带的WebBrowser控件,修改了下IE内核的版本,目前还是单线程的,逻辑挺简单的,萌新都能看懂. 废话不多说,上代码,附打包project. 链接:https://pa ...

  2. 好用到哭!8个技巧让Vim菜鸟变专家

    原文: https://juejin.im/post/5da68cb8f265da5b8c03c4a1 Vim只不过是一个文本编辑器,但如果你曾见过真正的高手是如何使用vim的,你就会知道,这个软件出 ...

  3. Java虚拟机内存区域详解

    JVM 运行时的数据区域 首先获取一个直观的认识: 总共也就这么 5 个区(直接内存不属于 JVM 运行时数据区的一部分),除了程序计数器其他的地方都有可能出现 OOM (OutOfMemoryErr ...

  4. 【fiddler安装】解决“Creation of the root certificate was not successful.”的问题

    问题:在安装过fiddler后,会出现“Creation of the root certificate was not successful.”的问题,这个是说证书安装不成功. 原因:在使用Fidd ...

  5. 【知识点】SPU&SKU

    SPU:标准化产品单元 SPU = Standard Product Unit (标准化产品单元),SPU是商品信息聚合的最小单位,是一组可复用.易检索的标准化信息的集合,该集合描述了一个产品的特性. ...

  6. vue中路由拦截无限循环的情况

    router.beforeEach(async (to, from, next) => { if (token) { if (whiteList.indexOf(to.path) != -1) ...

  7. Transformer---BERT模型

    一.BERT介绍 论文地址:BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding  BERT ...

  8. 51nod 1594 Gcd and Phi(莫比乌斯反演)

    题目链接 传送门 思路 如果这题是这样的: \[ F(n)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\phi(gcd(i,j)) \] 那么我们可能会想到下 ...

  9. AcWing 38. 二叉树的镜像

    习题地址 https://www.acwing.com/solution/acwing/content/2922/ 题目描述输入一个二叉树,将它变换为它的镜像. 样例 输入树: / \ / \ / \ ...

  10. angular 小技术点

    angular 标签 ng-options ng-model ng-checked ng-true-value ng-false-value ng-if ng-src delete $location ...