<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] > ### `Lock` * `synchronized`的缺陷,等待時間過長,需要有一種機制可以不讓等待的線程一直無期限地等待下去(比如只等待一定的時間或者能夠響應中斷),通過`Lock`就可以辦到。 * `Lock`不是Java語言內置的,`synchronized`是Java語言的關鍵字,因此是內置特性。`Lock`和`synchronized`有一點非常大的不同,采用`synchronized`不需要用戶去手動釋放鎖,當`synchronized`方法或者`synchronized`代碼塊執行完之后,系統會自動讓線程釋放對鎖的占用;而`Lock`則必須要用戶去手動釋放鎖,如果沒有主動釋放鎖,就有可能導致出現死鎖現象。 * `Lock`是一個接口,`ReentrantLock`是唯一實現了`Lock`接口的類。 * 不要將獲取鎖的過程寫在`try`塊中,因為如果在獲取鎖(自定義鎖的實現)時發生了異常,異常拋出的同時,也會導致鎖無故釋放。 <br/> > ### `Lock`與`synchronized`比較 ![](https://i.loli.net/2019/03/11/5c85d58d81a5a.png) <br/> > ### `Lock`接口的相關`api` ![](https://i.loli.net/2019/03/11/5c85d52e252f0.png) ``` public class Test { private ArrayList<Integer> arrayList = new ArrayList<Integer>(); private Lock lock = new ReentrantLock(); //注意這個地方 public static void main(String[] args) { final Test test = new Test(); new Thread(){ public void run() { test.insert(Thread.currentThread()); }; }.start(); new Thread(){ public void run() { test.insert(Thread.currentThread()); }; }.start(); } public void insert(Thread thread) { //加鎖 lock.lock(); try { System.out.println(thread.getName()+"得到了鎖"); for(int i=0;i<5;i++) { arrayList.add(i); } } catch (Exception e) { // TODO: handle exception }finally { System.out.println(thread.getName()+"釋放了鎖"); //釋放鎖 lock.unlock(); } } } ``` <br/> > ### `ReentrantLock` <br/> > ### `Condition` * `Condition`定義了等待/通知兩種類型的方法,當前線程調用這些方法時,需要提前獲取到`Condition`對象關聯的鎖。`Condition`對象是由`Lock`對象(調用`Lock`對象的`newCondition()`方法)創建出來的,換句話說,`Condition`是依賴`Lock`對象的。 * 一般都會將`Condition`對象作為成員變量。當調用`await()`方法后,當前線程會釋放鎖并在此等待,而其他線程調用`Condition`對象的`signal()`方法,通知當前線程后,當前線程才從`await()`方法返回,并且在返回前已經獲取了鎖。 > ### 三個線程 循環打印 ABC `lock condition` ``` public class LockConditionABC_3 { // lock condition 三個線程 循環打印 ABC // 參考 https://www.bbsmax.com/A/amd0ENEWzg/ public static void main(String[] args) throws InterruptedException { ReentrantLock lock = new ReentrantLock(); Condition conditionA = lock.newCondition(); Condition conditionB = lock.newCondition(); Condition conditionC = lock.newCondition(); Thread t1 = new Thread(new ThreadDemo(lock, conditionA, conditionB, 'A'), "ThreadA"); Thread t2 = new Thread(new ThreadDemo(lock, conditionB, conditionC, 'B'), "ThreadB"); Thread t3 = new Thread(new ThreadDemo(lock, conditionC, conditionA, 'C'), "ThreadC"); t1.start(); Thread.sleep(100); t2.start(); Thread.sleep(100); t3.start(); } static class ThreadDemo implements Runnable{ private final ReentrantLock reentrantLock; private final Condition thisCondtion; private final Condition nextCondtion; Character c; public ThreadDemo(ReentrantLock reentrantLock, Condition thisCondtion, Condition nextCondition, char c) { this.reentrantLock = reentrantLock; this.nextCondtion = nextCondition; this.thisCondtion = thisCondtion; this.c = c; } public void run(){ reentrantLock.lock(); try { // 連續打印 for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + ":" + c); // 使用nextCondition喚醒下一個線程 // 因為只有一個線程在等待,所以signal或者signalAll都可以 nextCondtion.signal(); // 不是最后一次則通過thisCondtion等待被喚醒 // 必須要加判斷,不然能夠打印6次 但6次后就會直接死鎖 if (i < 5 - 1) { try { // 本線程讓出鎖并等待喚醒 thisCondtion.await(); } catch (InterruptedException e) { e.printStackTrace(); } } } } finally { // 釋放鎖 reentrantLock.unlock(); } } } } ``` <br/> > ### `ReadWriteLock` * `ReadWriteLock`也是一個接口,`ReentrantReadWriteLock`是其的實現類,主要有兩個方法:`readLock()`和`writeLock()`用來獲取讀鎖和寫鎖。 * 讀是共享讀鎖,寫是獨占鎖阻塞其它的讀寫操作 ``` public class ReentrantReadWriteLockDemo { private static final Map<String, Object> map = new HashMap<String, Object>(); private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private static final Lock readLock = lock.readLock(); private static final Lock writeLock = lock.writeLock(); public ReentrantReadWriteLockDemo() { if(map.size() == 0 ) map.put("0", "asd"); } //讀寫鎖 //在同一時刻允許多個線程進行讀操作 //但是有線程進行寫操作時,阻塞其它線程的讀寫 public final Object get(String key, int threadId) { readLock.lock(); try { System.out.println("Thread: " + threadId + " > read " + key + "|" + map.get(key)); return map.get(key); } finally { readLock.unlock(); } } public final Object put(String key, Object value, int threadId) { writeLock.lock(); try { System.out.println("Thread: " + threadId + " > write " + key + " | " + value); SleepUtils.second(1000); return map.put(key, value); } finally { writeLock.unlock(); } } public final void clear() { writeLock.lock(); try { map.clear(); } finally { writeLock.unlock(); } } public static void main(String[] args) { ReentrantReadWriteLockDemo demo = new ReentrantReadWriteLockDemo(); for(int i = 0; i < 30; i++){ Thread thread = new Thread(new ThreadDemo(demo), String.valueOf(i)); thread.start(); } } public static class ThreadDemo implements Runnable{ ReentrantReadWriteLockDemo demo ; public ThreadDemo(ReentrantReadWriteLockDemo demo){ this.demo = demo; } public void run() { int i = Integer.valueOf(Thread.currentThread().getName()); if(i % 10 == 0){ demo.put(String.valueOf(i), Thread.currentThread().getName(), i); }else{ demo.get(String.valueOf(0), i); } } } static class SleepUtils{ public static void second(int i){ try { Thread.sleep(i); } catch (InterruptedException e) { e.printStackTrace(); } } } } ``` <br/> <br/> *** 參考: [ReentrantLock(重入鎖)以及公平性](http://ifeve.com/reentrantlock-and-fairness/)
                  <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>

                              哎呀哎呀视频在线观看