<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ### **JUC LinkedBlockingQueue** java.util.concurrent.LinkedBlockingQueue是一個基于單向鏈表,范圍任意的(其實是有界的),FIFO阻塞隊列。訪問與移除操作是在隊頭進行,添加操作是在隊尾進行,并分別使用不同的鎖進行保護,只有在可能涉及多個節點的操作才同時對兩個鎖進行加鎖, 隊列是否為空,是否已滿任然是通過元素數量的計算器,(count)進行判斷,由于可以同時在隊頭,隊尾并發地進行訪問,添加操作,所以這個計數器必須是線程安全的,這里使用了一個原子類,AtomicInteger,這就決定了它的容量范圍是1-integer.MAX_VALUE.。 ### **源碼解析** ``` //內部構造方法 public LinkedBlockingQueue(){ this(Integer.MAX_VALUE); } ``` 實例化時如果未給初始控制值,則按照Integer最大值(2的31次方-1)去走 當實例化時給了一個初始化空間值。 ~~~ //內部構造方法 public LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node<E>(null); } ~~~ 當capacity的值等于或者小于0時,則拋出IllegalArgumentException,最后鏈表的隊頭和隊尾都初始化為空。 ## **在說第三個構造函數時,先看一下ReentrantLock是什么東西,跟synchronized有什么區別** 1. synchronized是獨占鎖,加鎖和解鎖的過程是自動進行,易于操作,但不夠靈活。 ReentrantLock也是獨占鎖,加鎖和解鎖的過程是手動進行,不易于操作,但非常靈活 2. synchronized是可重入鎖,以為加鎖和解鎖是自動進行,不必擔心最后是否釋放鎖; ReentrantLock也可重入鎖,但加鎖和解鎖是手動進行,且次數需一樣,否則其他線程無法得到鎖。 3. Synchronized不可響應中斷,一個線程獲取不到鎖就一直等著; ReentrantLock可以響應中斷 使用: ``` private static final Lock lock = new ReentrantLock(); public static void main(String[] args) { new Thread( ()-> test(),"線程A").start(); new Thread( ()-> test(),"線程B").start(); } public static void test(){ try { lock.lock(); System.out.println(Thread.currentThread().getName()+"獲取了鎖"); TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }finally { System.out.println(Thread.currentThread().getName()+"釋放了鎖"); lock.unlock(); } } ``` 執行結果是: ``` 線程A獲取了鎖 線程A釋放了鎖 線程B獲取了鎖 線程B釋放了鎖 ``` 看一下把test方法加上synchronized 注釋掉lock.lock()和lock.unlock() 其執行結果是一致的,那不同點在哪呢?那就是公平鎖的實現。 ``` private static final Lock lock = new ReentrantLock(true); public static void main(String[] args) { new Thread( ()-> test(),"線程A").start(); new Thread( ()-> test(),"線程B").start(); new Thread( ()-> test(),"線程C").start(); } public static void test(){ for(int i =0;i<2;i++){ try { lock.lock(); System.out.println(Thread.currentThread().getName()+"獲取了鎖"); TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }finally { System.out.println(Thread.currentThread().getName()+"釋放了鎖"); lock.unlock(); } } } ``` 在初始化時加上了公平鎖策略,構造參數值為true 上面代碼執行結果如下列: 左邊是使用ReentranyLock鎖,右邊是使用synchronized ![](https://img.kancloud.cn/fb/57/fb579bdb7d6d8caf82801429f101ba00_669x467.png) 使用ReentranLock公平鎖,會按照順序執行。 非公平鎖: &nbsp;&nbsp;&nbsp;&nbsp;非公平鎖那就隨機的獲取,看cpu時間片輪到哪個線程,哪個線程就能獲取鎖,和上面公平鎖的區別很簡單,就在于實例化時構造參數為false或者true,默認為false。 響應中斷: &nbsp;&nbsp;&nbsp;&nbsp;響應中斷就是一個線程獲取不到鎖,不會一直等下去,Reentranlock會給予一個中斷回應。看下面代碼: ``` public class aaa { static final Lock lock = new ReentrantLock(); static final Lock lock1 = new ReentrantLock(); public static void main(String[] args) { Thread thread = new Thread(new ThreadA(lock,lock1)); Thread thread1 = new Thread(new ThreadA(lock,lock1)); thread.start(); thread1.start(); thread.interrupt(); } } class ThreadA implements Runnable{ Lock firstLock; Lock sencondLock; public ThreadA(Lock firstLock,Lock sencondLock){ this.firstLock = firstLock; this.sencondLock = sencondLock; } @Override public void run() { try { firstLock.lockInterruptibly(); TimeUnit.SECONDS.sleep(5); sencondLock.lockInterruptibly(); } catch (InterruptedException e) { e.printStackTrace(); }finally { firstLock.unlock(); sencondLock.unlock(); System.out.println(Thread.currentThread().getName()+"獲取到了資源,正常結束"); } } } ``` 定義了兩個鎖,lock和lock1,然后使用兩個線程thread和thread1造成是說場景。正常情況下,這兩個線程相互等待獲取資源而處于死循環狀態。但是thread中斷,另外一個線程就可以獲取到資源,正常執行, 限時等待: &nbsp;&nbsp;&nbsp;&nbsp;通過tryLock方法來實現,可以選擇傳入時間參數,表示等待指定的時間,無參則表示立即返回鎖申請的結果,true表示獲取鎖成功,false表示獲取鎖失敗,可以用這種發放解決死鎖的問題。 ### **回到原文** ``` //LinkedBlockingQueue第三構造方法 public LinkedBlockingQueue(Collection<? extends E> c) { this(Integer.MAX_VALUE); final ReentrantLock putLock = this.putLock; putLock.lock(); // Never contended, but necessary for visibility try { int n = 0; for (E e : c) { if (e == null) throw new NullPointerException(); if (n == capacity) throw new IllegalStateException("Queue full"); enqueue(new Node<E>(e)); ++n; } count.set(n); } finally { putLock.unlock(); } } ``` 傳入一個集合,創建一個容量為這個集合的LinkedBlockingQueue,并且按照集合迭代器順序添加。 這里使用ReentranLock鎖來實現同步并且線程安全。 初始化給了Integer的最大值。并創建了一個鎖,并鎖當前方法 迭代傳入的集合,當集合內的元素為null時 拋出一個空指針異常。當計數類的數值等于數組內的元素的個數時,會拋出Queue Full 異常。<br/><br/> ``` public int size() { return count.get(); } ``` 獲取當前已使用的容量。是通過原子類AtomicInteger的get方法獲取<br/><br/> ~~~ public int remainingCapacity() { return capacity - count.get(); } ~~~ 獲取剩余容量,是通過最大的容量減已使用的容量<br/><br/> ~~~ public void put(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); int c = -1; Node<E> node = new Node<E>(e); final ReentrantLock putLock = this.putLock; final AtomicInteger count = this.count; putLock.lockInterruptibly(); try { while (count.get() == capacity) { notFull.await(); } enqueue(node); c = count.getAndIncrement(); if (c + 1 < capacity) notFull.signal(); } finally { putLock.unlock(); } if (c == 0) signalNotEmpty(); } ~~~ 在隊列的尾部添加元素 未寫完。。。。。。。。(2020年03月24日16:50)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看