模仿ReentrantLock類自定義鎖
阿新 • • 發佈:2018-02-12
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類自定義鎖