共享锁:线程可以同时持有。
实现代码如下:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
* 共享锁
*/
public class SharedLock implements Lock {
//同步器,初始化创建放在本类中的构造方法中
private Sync sync;
//构造方法,初始化同步器的计数值
public SharedLock(int count) {
sync = new Sync(count);
}
// 静态内部类,同步器!继承AQS,是实现锁的核心
private class Sync extends AbstractQueuedSynchronizer {
//构造方法,先判断值是否为正,正则将值放入放入计数中。
Sync(int count){
if (count < 0){
throw new IllegalArgumentException();
}
setState(count);
}
/**
* 获取锁 真正的实现方法
* 通过for 死循环来确保CAS的正常完成
* 或者剩余数量如果小于0 也直接返回
* @param acquire 请求锁的个数
* @return
*/
@Override
protected int tryAcquireShared(int acquire) {
for (;;){
// 当前可用的锁数量
int available = getState();
// 减去使用掉的锁,剩余的锁数量
int remaining = available - acquire;
// compareAndSetState(available,remaining)保证线程安全,将剩余锁设置为剩余的数量
if (remaining < 0 || compareAndSetState(available,remaining)){
return remaining;
}
}
}
/**
* 释放锁 真正的实现方法
* @param release 释放锁的个数
* @return
*/
@Override
protected boolean tryReleaseShared(int release) {
for (;;){
// 当前剩余
int current = getState();
// 总计
int count = current + release;
// 判断释放的是否为负值!
if (count < current){
throw new Error("Maximum permit count exceeded");
}
if (compareAndSetState(current,count)){
return true;
}
}
}
protected final Condition newCondition(){
return new ConditionObject();
}
}
/**
* 面向使用者,获取一个共享锁
*/
@Override
public void lock() {
sync.acquireShared(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
/**
* 尝试获取一个共享锁
* @return true 获取成功
* false 获取失败
*/
@Override
public boolean tryLock() {
return sync.tryAcquireShared(1) >= 0;
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireSharedNanos(1,unit.toNanos(time));
}
/**
* 面向使用者,释放一个共享锁
*/
@Override
public void unlock() {
sync.releaseShared(1);
}
@Override
public Condition newCondition() {
return sync.newCondition();
}
}
测试:
public class SharedLockTest {
private SharedLock lock = new SharedLock(3);
private static CountDownLatch countDownLatch = new CountDownLatch(1);
private class Test extends Thread{
@Override
public void run() {
try {
countDownLatch.await();
if (lock.tryLock()){
System.out.println(Thread.currentThread().getName() + "获取了一个锁!" + System.currentTimeMillis());
Thread.sleep(3000);
lock.unlock();
}else {
System.out.println(Thread.currentThread().getName());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SharedLockTest test = new SharedLockTest();
for (int i = 0;i<10;i++){
Test t = test.new Test();
t.start();
}
countDownLatch.countDown();
}
}