日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AQS理解之三,由刚才写的锁转变成一个公平锁

發布時間:2024/9/30 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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理解之三,由刚才写的锁转变成一个公平锁的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。