AQS理解之三,由刚才写的锁转变成一个公平锁
生活随笔
收集整理的這篇文章主要介紹了
AQS理解之三,由刚才写的锁转变成一个公平锁
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
AQS理解之三,由剛才寫的鎖轉變成一個公平鎖
在第二節里我們實現了一個不公平的鎖,之所以說它不公平,主要是因為加鎖后解鎖時,阻塞的其他線程獲取到的鎖的可能是隨機的,并不是按照順序來確定的,如果要轉變為公平鎖,我們應該要記錄這個進入的順序,并在解鎖時必須滿足是第一個阻塞等待的線程才解鎖。
其次,在上一節我們實現的鎖是一個自旋阻塞等待的,這樣的話線程還是在繼續白白工作的,我們在這里也進行優化,使用LockSupport來優化。
我們定義一個鏈表來保存阻塞的線程,在取出時從鏈表中取出即可。
這里我們實現了一個簡單的公平鎖,用Node鏈表保存了阻塞的線程,在unlock時取出最先的一個進行解鎖。
class MyLock{private Thread ownerThread;private volatile AtomicInteger state;private boolean isFair;private volatile Node head;static class Node{private volatile Node pre;private volatile Node next;private volatile Thread thread;public Node(Thread thread){this.thread = thread;}@Overridepublic String toString() {return "Node{" +", thread=" + thread==null?"null":thread.getName() +'}';}}public MyLock(boolean isFair){state = new AtomicInteger(0);head = new Node(null);this.isFair = isFair;}public Thread getOwnerThread() {return ownerThread;}public void setOwnerThread(Thread ownerThread) {this.ownerThread = ownerThread;}public boolean lock(){//可重入for (;;) {if (Thread.currentThread() == getOwnerThread()){state.incrementAndGet();return true;}else if(state.compareAndSet(0,1)) {System.out.println(Thread.currentThread());setOwnerThread(Thread.currentThread());return true;}if (isFair){Node temp = head;while(temp.next !=null){temp = temp.next ;}//將阻塞的線程放入鏈表的隊尾。temp.next = new Node(Thread.currentThread());temp.next.pre = temp;LockSupport.park();}}public void unlock(){if (Thread.currentThread() != getOwnerThread()){throw new RuntimeException("不是鎖持有線程,不能解鎖");}setOwnerThread(null);state.decrementAndGet();if(isFair){Node temp = head;Node unlockNode = head.next;if (unlockNode!=null&&unlockNode.thread!=null){LockSupport.unpark(unlockNode.thread);temp.next = unlockNode.next;if(unlockNode.next!=null){unlockNode.next.pre = temp;}}Node temp1 = head;while (temp1!=null){System.out.println("unlock"+temp1.thread);temp1 = temp1.next;}}} }但是需要注意,我們這里的代碼是錯誤的,因為對head節點的操作位于多個線程,而代碼里的操作不是原子性的,所以會有問題,所以我們可以用AtomicReference變量來存儲,借助這個類來實現原子操作
總結
以上是生活随笔為你收集整理的AQS理解之三,由刚才写的锁转变成一个公平锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AQS理解之二,自己设计一个锁
- 下一篇: AQS理解之四—看看我们写的和 Reen