ReentrantLock

一个reentrant互斥锁和synchronized修饰的方法或代码作用大致相同,但它拥有着一些扩展性的功能。
使用案例:

class X {
private final ReentrantLock lock = new ReentrantLock();
 // ...

public void m() {
 lock.lock();  // block until condition holds
 try {
    // ... method body
  } finally {
    lock.unlock()
  }
}
}}

代码:

public class ReentrantLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = 7373984872572414699L;
/*提供实现AbstractQueuedSynchronizer 同步器的方法 */

Sync类作为ReentrantLock 的内部辅助类,继承于AbstractQueuedSynchronizer 用来实现AQS的一些同步方法并被它的子类NonfairSync 和FairSync 所使用
它直接为非公平锁类提供了nonfairTryAcquire方法,这个方法也是默认Acquire方法调用的对象
tryRelease:公平锁和非公平锁共用的释放锁方法

private final Sync sync;
/**子类在下面有公平和非公平版本的实现,使用AQS的状态标识(state)来代表持有锁的被占有情况
 */
abstract static class Sync extends AbstractQueuedSynchronizer {
    private static final long serialVersionUID = -5179523762034025860L;
    abstract void lock();
    /*执行非公平tryLock*/
    final boolean nonfairTryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        /*首先调用AQS的getState方法来获取state状态,值默认初始为0*/
        int c = getState();
    /*为0,证明没有线程持有锁,利用原子操作将state+1,并将当前线程设为当前独享模式的持有者,然后返回true*/
        if (c == 0) {
            if (compareAndSetState(0, acquires)) {
                setExclusiveOwnerThread(current);
                return true;
            }
        }
     /*若锁已被当前线程所占有,即状态值不为0,则将当前状态值设置为:当前状态值加上acquires参数(默认为1)。然后返回true。这块代码为可重入的体现*/
        else if (current == getExclusiveOwnerThread()) {
            int nextc = c + acquires;
            if (nextc < 0) // overflow
                throw new Error("Maximum lock count exceeded");
                /*设置状态值为修改后的值*/
            setState(nextc);
      /*成功获锁*/
            return true;
        }
        /*获取失败返回false*/
        return false;
    }
    protected final boolean tryRelease(int releases) {
        /*将当前状态值减去releases(默认1)*/
        int c = getState() - releases;
        if (Thread.currentThread() != getExclusiveOwnerThread())
            throw new IllegalMonitorStateException();
         /*标志位,若c=0,则返回true,不为0.返回false*/
        boolean free = false;
        /*若修改后的状态值为0,则证明可以释放,并将持有当前独享模式的线程置空*/
        if (c == 0) {
        /*设置标志位为0*/
            free = true;
            setExclusiveOwnerThread(null);
        }
        /*设置修改后的状态值*/
        setState(c);
        return free;
    }
    /*判断是否持有独享模式*/
    protected final boolean isHeldExclusively() {
        return getExclusiveOwnerThread() == Thread.currentThread();
    }

非公平锁的实现类,继承于Sync

    /*非公平锁*/
static final class NonfairSync extends Sync {
    private static final long serialVersionUID = 7316153563782823691L;
    final void lock() {
    /*设置当前线程为独享模式的持有者,若当前state为0并且通过原子操作,则将其设为持有者,否则调用AQS的aquire方法*/
        if (compareAndSetState(0, 1))
            setExclusiveOwnerThread(Thread.currentThread());
        else
            acquire(1);
    }
    /*尝试获锁,默认非公平锁,调用nonfairTryAcquire方法*/
    protected final boolean tryAcquire(int acquires) {
        return nonfairTryAcquire(acquires);
    }
}

公平锁的实现类,继承于Sync

/*公平锁*/
static final class FairSync extends Sync {
    private static final long serialVersionUID = -3000897897090466540L;
    final void lock() {
        acquire(1);
    }
    protected final boolean tryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        /*获取state值*/
        int c = getState();
        /*公平的体现。若state为0*/
        if (c == 0) {
        /*当前节点为等待队列头节点并且能将state设置为acquires标识的值,则成功*/
            if (!hasQueuedPredecessors() &&
                compareAndSetState(0, acquires)) {
                setExclusiveOwnerThread(current);
                return true;
            }
        }
         /*若锁已被当前线程所占有,即状态值不为0,则将当前状态值设置为:当前状态值加上acquires参数(默认为1)。然后返回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;
    }
}



/*创建一个ReentrantLock的实例,这和使用ReentrantLock(flase)是一样的*/
public ReentrantLock() {
    sync = new NonfairSync();
}
/*获锁*/
public void lock() {
    sync.lock();
}
/*释放锁*/
public void unlock() {
    sync.release(1);
}

使用:

package aa;
import java.util.concurrent.locks.ReentrantLock;
public class Aa {
static ReentrantLock lock = new ReentrantLock(true);
static class Bb implements Runnable {
    int id;
    public Bb(Integer id) {
        this.id = id;
    }
  public void run() {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for(int i=0;i<3;i++){
            lock.lock();
            System.out.println("获得锁的线程:"+id);
            lock.unlock();
        }
    }
}
public static void main(String[] args)  {
    for(int i=0;i<7;i++){
        new Thread(new Bb(i)).start();
    }
}

}
上面是公平锁的实现代码。运行后可以看到0到6几乎不重复出现,而非公平锁只需将true改为false,运行后可以发现0~6会成堆重复出现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值