<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] # ReadWriteLock ReadWriteLock也是一個接口,在它里面只定義了兩個方法: ~~~ public interface ReadWriteLock { /** * Returns the lock used for reading. * * @return the lock used for reading. */ Lock readLock(); /** * Returns the lock used for writing. * * @return the lock used for writing. */ Lock writeLock(); } ~~~ 一個用來獲取讀鎖,一個用來獲取寫鎖。也就是說將文件的讀寫操作分開,分成2個鎖來分配給線程,從而使得多個線程可以同時進行讀操作。下面的ReentrantReadWriteLock實現了ReadWriteLock接口。 # ReentrantReadWriteLock ReentrantReadWriteLock里面提供了很多豐富的方法,不過最主要的有兩個方法:readLock()和writeLock()用來獲取讀鎖和寫鎖。 下面通過幾個例子來看一下ReentrantReadWriteLock具體用法。 ## synchronized實現 我們先看一下,多線程同時讀取文件時,用synchronized實現的效果 ~~~ package testThread; import java.util.concurrent.locks.ReentrantReadWriteLock; public class TestThread { private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); public static void main(String[] args) { final TestThread testThread = new TestThread(); new Thread() { public void run() { testThread.get(Thread.currentThread()); } }.start(); new Thread() { public void run() { testThread.get(Thread.currentThread()); } }.start(); } private synchronized void get(Thread thread) { long start = System.currentTimeMillis(); while (System.currentTimeMillis() - start <= 1) { System.out.println(thread.getName() + "正在進行讀操作"); } System.out.println(thread.getName() + "讀操作完畢"); } } ~~~ 這些線程是一次執行的 ## 讀寫鎖讀操作 用讀寫鎖的話: ~~~ package com.study; import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadAndWriteLock { /** * 獲取讀寫鎖 */ ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public void get(Thread thread) { //用讀鎖鎖定 lock.readLock().lock(); try { System.out.println("start time: " + System.currentTimeMillis()); for (int i = 0; i < 5; i++) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(thread.getName() + " 正在進行讀操作---"); } System.out.println(thread.getName() + " 讀操作完畢---"); System.out.println("end time: " + System.currentTimeMillis()); } finally { lock.readLock().unlock(); } } public static void main(String[] args) { ReadAndWriteLock lock = new ReadAndWriteLock(); new Thread(() -> lock.get(Thread.currentThread())).start(); new Thread(() -> lock.get(Thread.currentThread())).start(); } } ~~~ 說明thread1和thread2在同時進行讀操作。 這樣就大大提升了讀操作的效率。 這樣就很巧妙的解決synchronized的一個性能問題:讀與讀之間互斥 ## 讀寫鎖的互斥 ~~~ package com.study; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadAndWriteLock { /** * 獲取讀寫鎖 */ ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); /** * 讀操作 */ public void readFile(Thread thread) { //獲取讀鎖 lock.readLock().lock(); //判斷是不是寫鎖 boolean readLock = lock.isWriteLocked(); if (!readLock) { System.out.println("當前為讀鎖!"); } try { for (int i = 0; i < 5; i++) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(thread.getName() + "正在進行讀操作"); } System.out.println(thread.getName() + "讀操作完畢"); } finally { System.out.println("釋放讀鎖"); lock.readLock().unlock(); } } /** * 寫操作 */ public void writeFile(Thread thread) { //獲取寫鎖 lock.writeLock().lock(); //判斷是不是寫鎖 boolean readLock = lock.isWriteLocked(); if (readLock) { System.out.println("當前為寫鎖!"); } try { for (int i = 0; i < 5; i++) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(thread.getName() + "正在進行寫操作"); } System.out.println(thread.getName() + "寫操作完畢"); } finally { System.out.println("釋放寫鎖"); lock.writeLock().unlock(); } } public static void main(String[] args) { ReadAndWriteLock lock = new ReadAndWriteLock(); //建立n個線程同時讀 ExecutorService service = Executors.newCachedThreadPool(); service.execute(new Runnable() { @Override public void run() { //測試2個寫鎖 //lock.writeFile(Thread.currentThread()); lock.readFile(Thread.currentThread()); } }); //建立n個線程同時寫 ExecutorService service1 = Executors.newCachedThreadPool(); service1.execute(new Runnable() { @Override public void run() { //測試2個讀鎖 //lock.readFile(Thread.currentThread()); lock.writeFile(Thread.currentThread()); } }); } } ~~~ # 注意 不過要注意的是,如果有一個線程已經占用了讀鎖,則此時其他線程如果要申請寫鎖,則申請寫鎖的線程會一直等待釋放讀鎖。 如果有一個線程已經占用了寫鎖,則此時其他線程如果申請寫鎖或者讀鎖,則申請的線程會一直等待釋放寫鎖。 鎖降級:寫鎖--沒釋放--可以降級到讀鎖 鎖升級:讀鎖-沒釋放--可以升級到寫鎖 在分布式場景下,像讀寫鎖這樣的鎖,加入不用鎖降級的方式,可能會出現臟讀的現象
                  <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>

                              哎呀哎呀视频在线观看