1. 程式人生 > >模仿ReentrantLock類自定義鎖

模仿ReentrantLock類自定義鎖

strong down [] internal bsp ride 獲取 sets ktr

簡介

臨近過年了,沒什麽需求,今天模仿ReentrantLock自定義寫了一個自己鎖,在這裏記錄一下,前提是對AQS原理有所了解,分享給大家

1、自定義鎖MyLock

package com.jacky;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * Created by jacky on 2018/2/12.
 
*/ public class MyLock implements Lock{ private final Sync sync; /** * 創建公平鎖或非公平鎖 * @param fairFlag */ public MyLock(boolean fairFlag){ sync = fairFlag ? new FairSync() : new NonFairSync(); } /** * 默認是公平鎖 */ public MyLock(){ sync = new FairSync(); }
/** * 獲取鎖 */ @Override public void lock() { sync.acquire(1); } /** * 獲取可中斷鎖 * @throws InterruptedException */ @Override public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } /** * 它表示用來嘗試獲取鎖,如果獲取成功,則返回true,如果獲取失敗(即鎖已被其他線程獲取),則返回false, * 也就說這個方法無論如何都會立即返回。在拿不到鎖時不會一直在那等待 *
@return */ @Override public boolean tryLock() { return sync.nonfairTryAcquire(1); } /** * 獲得可超時的鎖 * @param time * @param unit * @return * @throws InterruptedException */ @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.new ConditionObject(); } abstract static class Sync extends AbstractQueuedSynchronizer { /** * 判斷當前線程是否獲得鎖 * @return */ @Override protected boolean isHeldExclusively() { return Thread.currentThread() ==getExclusiveOwnerThread(); } /** * 嘗試釋放鎖 * @param arg * @return */ @Override protected boolean tryRelease(int arg) { int newState =getState()-arg; setState(newState < 0 ? 0:newState); if (newState ==0){ setExclusiveOwnerThread(null); } return true; } final boolean nonfairTryAcquire(int arg) { Thread thread = Thread.currentThread(); int state = getState(); if (state ==0){ compareAndSetState(0,state+arg); //設置獨占線程 setExclusiveOwnerThread(thread); return true; } if (isHeldExclusively()){ setState(state+arg); return true; } return false; } } static class FairSync extends Sync{ /** * 嘗試公平鎖獲得鎖 * @param arg * @return */ @Override public boolean tryAcquire(int arg) { Thread thread = Thread.currentThread(); int state = getState(); if (state ==0){ //判斷隊列是否有數據,有數據就返回獲取鎖失敗(公平鎖才會這麽做) if (hasQueuedPredecessors()){ return false; } compareAndSetState(0,state+arg); //設置獨占線程 setExclusiveOwnerThread(thread); return true; } if (isHeldExclusively()){ setState(state+arg); return true; } return false; } } static class NonFairSync extends Sync{ @Override public boolean tryAcquire(int arg) { return nonfairTryAcquire(arg); } } }

2、測試類

package com.jacky;

import jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by jacky on 2018/2/12.
 */
public class MyLockDemo {
    private final static MyLock lock = new MyLock(false);
    //private final static ReentrantLock lock = new ReentrantLock(true);
    private static int num = 0;
    public static void main(String[] args) {
        int count = 2000;
        CountDownLatch countDownLatch = new CountDownLatch(count);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    lock.lock();
                Thread thread = Thread.currentThread();
                System.out.println("--start--"+thread.getName());
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                num++;
                System.out.println("--end--");
                countDownLatch.countDown();
                }finally {
                   lock.unlock();
                }

            }
        };
        Thread thread = null;
        for (int i = 0; i < count; i++) {
            thread = new Thread(runnable,"t"+i);
            thread.start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("--num--"+num);
    }
}

模仿ReentrantLock類自定義鎖