Linux快捷方式

postman小技巧

  返回  

公平锁实现

2021/8/20 15:59:01 浏览:

为了实现公平锁,我们可以看下ReentrantLock类中的源码是如何写的。因为在ReentrantLock类中默认是非公平锁,但是我们可以指定为公平锁。

那么,可以直接提取一个公平锁的封装出来:

FairLock.java

public class FairLock implements Lock {

    private final Sync sync = new Sync();

    @Override
    public void lock() {
        sync.acquire(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(time));
    }

    @Override
    public void unlock() {
        sync.release(1);
    }

    @Override
    public Condition newCondition() {
        return sync.newCondition();
    }

    static final class Sync extends AbstractQueuedSynchronizer{
        // 判断是否已经锁
        protected final boolean isHeldExclusively() {
            return getState() == 1;
        }

        // 如果没锁,尝试获取
        protected boolean tryAcquire(int acquires){
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                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;
        }

        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }

        final ConditionObject newCondition() {
            return new ConditionObject();
        }
    }
}

AbstractQueuedSynchronizer类也就是抽象同步队列的意思。这个也就是我们经常看见的AQS。它是实现同步器的基础组件,并发包中锁的底层实现就是AQS实现的。

然后,可以定义一个测试类:

public class JoinTest {

    private static volatile int value = 0;

    public static void main(String[] args) {
        FairLock fairLock = new FairLock();

        Thread newThread1 = ThreadFactory.getNewThread(new Runnable() {
            @Override
            public void run() {
                fairLock.lock();
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName() + " . value is : " + value++);
                }
                fairLock.unlock();
            }
        });

        Thread newThread2 = ThreadFactory.getNewThread(new Runnable() {
            @Override
            public void run() {
                fairLock.lock();
                for (int i = 10; i >= 0; i--) {
                    System.out.println(Thread.currentThread().getName() + " . value is : " + value--);
                }
                fairLock.unlock();
            }
        });

        newThread1.start();
        newThread2.start();

    }

    static class ThreadFactory{
        private static AtomicInteger integer = new AtomicInteger(1);
        public static Thread getNewThread(Runnable r){
            return new Thread(r, "Thread#"+integer.getAndIncrement());
        }
    }

}

我们知道公平锁是按照先后顺序依次执行的,不妨看下执行的结果:

在这里插入图片描述
可以看出,确实是遵循这个先后执行规则的。也就是一个简易版的公平锁。

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号