public class SynchronizedTest { // 实例方法,方法访问标志ACC_SYNCHRONIZED,锁对象是对象实例 public synchronized void test1(){} // 静态方法,方法访问标志ACC_SYNCHRONIZED,锁对象是MetaSpace中的Class // 至关于类的全局锁,会锁住全部调用该方法的线程 public synchronized static void test2(){} public void test3() { //同步代码块,在代码块前增长monitorenter指令,代码块后增长monitorexit指令 SynchronizedTest synchronizedTest = new SynchronizedTest(); synchronized (synchronizedTest) {} // 类锁,效果等同于锁静态方法。代码块先后增长monitorenter、monitorexit指令 synchronized (SynchronizedTest.class) {} } }
可jclasslib查看Acc_SYNCHRONIZED标志和monitorenter、monitorexit指令html
test1 方法:java
Access flags: 0x0021[public synchronized]
test2 方法:node
Access flags: 0x0029[public static synchronized]
test3方法Code操做码:c#
0 new #2 <com/java/study/jvm/SynchronizedTest> 3 dup 4 invokespecial #3 <com/java/study/jvm/SynchronizedTest.<init>> 7 astore_1 8 aload_1 9 dup 10 astore_2 11 monitorenter 12 aload_2 13 monitorexit 14 goto 22 (+8) 17 astore_3 18 aload_2 19 monitorexit 20 aload_3 21 athrow 22 ldc #2 <com/java/study/jvm/SynchronizedTest> 24 dup 25 astore_2 26 monitorenter 27 aload_2 28 monitorexit 29 goto 39 (+10) 32 astore 4 34 aload_2 35 monitorexit 36 aload 4 38 athrow 39 return
核心组件并发
图示过程:jvm
解释:函数
ReentrantLock初始化时,会new一个同步类(默认非公平NonfairSync,当传入公平参数fair=true时,则new公平类FairSync);而FairSync 和NonfairSync都继承ReentrantLock中内部类Sync,Sync则继承同步器AbstractQueuedSynchronizer。UML图以下(http://www.javashuo.com/article/p-ahbodinp-ny.html 截取):性能
public class ReentrantLock implements Lock, java.io.Serializable { abstract static class Sync extends AbstractQueuedSynchronizer { final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { //第2次尝试获取锁 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; } } static final class NonfairSync extends Sync { final void lock() { // 可不进入队列,直接抢锁 if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } } }
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable { public final void acquire(int arg) { // 步骤3,加入等待队列,默认排他锁 if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
而继续addWaiter、enq和acquireQueued则是实现如下图示过程:
优化
private Node addWaiter(Node mode) { Node node = new Node(Thread.currentThread(), mode); // Try the fast path of enq; backup to full enq on failure Node pred = tail; if (pred != null) { node.prev = pred; if (compareAndSetTail(pred, node)) { pred.next = node; return node; } } //前置节点为null的临界条件,第一个线程进入等待队列 enq(node); return node; }
前置节点为null的临界条件,第一个线程进入等待队列,进行初始化ui
private Node enq(final Node node) { for (;;) { Node t = tail; if (t == null) { // Must initialize //队列初始化 if (compareAndSetHead(new Node())) tail = head; } else { //双向链表添加元素 node.prev = t; if (compareAndSetTail(t, node)) { t.next = node; return t; } } } }
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; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } finally { if (failed) cancelAcquire(node); } }
node属性值介绍:
对应源码:
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable { static final class Node { static final Node EXCLUSIVE = null; static final int CANCELLED = 1; static final int SIGNAL = -1; static final int CONDITION = -2; static final int PROPAGATE = -3; volatile int waitStatus; volatile Node prev; volatile Node next; volatile Thread thread; Node nextWaiter; final boolean isShared() { return nextWaiter == SHARED; } final Node predecessor() throws NullPointerException { Node p = prev; if (p == null) throw new NullPointerException(); else return p; } Node() { // Used to establish initial head or SHARED marker } Node(Thread thread, Node mode) { // Used by addWaiter this.nextWaiter = mode; this.thread = thread; } Node(Thread thread, int waitStatus) { // Used by Condition this.waitStatus = waitStatus; this.thread = thread; } } }
重入锁的可重复进入在如下代码中实现(非公平锁示例,公平锁代码同样):
final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { ... } // c > 0 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; }
第一处不公平地方(lock方法):
static final class NonfairSync extends Sync { final void lock() { // 可不进入队列,直接抢锁 if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } }
static final class FairSync extends Sync { final void lock() { acquire(1); } }
第二处不公平的地方(tryAcquire):
static final class NonfairSync extends Sync { protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } }
abstract static class Sync extends AbstractQueuedSynchronizer { final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { //发现锁被释放时,可直接抢锁 if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } ... } }
公平锁
static final class FairSync extends Sync { 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; } } ... } }
第三处不公平地方,加入队列时,前置节点是头节点:
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)) { ... } } }