浅析 ReentrantLock对象和synchronized关键字
浅析 ReentrantLock对象和synchronized关键字
看过suhuanzheng7784877同学的并发加锁机制后,然后结合自己的一些理解也来讲讲锁,以便日后回顾和复习。
在我接触的锁机制的有两种锁,一种就是单原子加锁, 一种就是synchronized加锁,而前者是通过程序控制单原子变量实现,而后者是有jvm控制。
先不说执行的效率,竟然程序也能实现锁,让我们看看锁到底怎么实现的,ReentrantLock就是实现了单原子加锁。
先想想什么是单原子加锁? 在我所接触当中,我的理解是通过程序控制基本类型数据。一般是通过 int 数据,及申明一个int变量,我们通过程序维护它的并发。
所以,说一种最简单的最通俗的 就是:当一个线程使用某个对象的时候,先判断该对象里面的int变量, 如果是0说明还没有线程使用它, 如果是1,说明有线程使用它,所以就进入等待(这里是需要靠程序实现的)。
那么我们就来看看ConcurrentHashMap类吧,先简单的介绍下它,它和hashTable的功能差不多都是实现了同步功能。
那么在ConcurrentHashMap里面就有一个Segment对象(差不多ConcurrentHashMap的方法都是调用Segment方法,所以我们先不去想ConcurrentHashMap也不谈它的特性,就直接看Segment的put方法):
V put(K key, int hash, V value, boolean onlyIfAbsent) { lock(); try { 。。。。。。省略了 } finally { unlock(); } } final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); }public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }final boolean acquireQueued(final Node node, int arg) { try { boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC return interrupted; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } catch (RuntimeException ex) { cancelAcquire(node); throw ex; } }