我們知道多個執行緒同時讀一個資源類別是沒有任何問題的,所以在並發的情況下,讀取共享資源應該是可以同時進行的;但是,如果一個執行緒想要去寫共享資源,就不應該再有其他執行緒同時對該共享資源進行讀取或是寫操作了。
(推薦教學:java入門教學)
我們想要的是:允許多個執行緒同時讀,但只要有一個執行緒在寫,其他執行緒就必須等待。
讀寫鎖定就是這個原理,即讀寫鎖在同一時刻可以允許多個多線程訪問,但是在寫線程訪問的時候,所有的讀取線程和其他寫線程都會被阻塞。讀寫鎖實際維護了一對鎖,一個讀鎖,一個寫鎖,透過分離讀鎖和寫鎖,使得其並發性比獨佔式鎖(排他鎖)有了很大的提升。
程式碼範例:
public class ReadWriteLockDemo { public static void main(String[] args) { ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); Book book = new Book();//创建一本书,可读可写 //两个写手 for (int i = 0; i < 2; i++) { int num = i; new Thread(()->{ try { readWriteLock.writeLock().lock(); System.out.println("写手"+num+"在写文章"); book.write(String.valueOf(num),UUID.randomUUID().toString().substring(0,5)); }catch (Exception e){ e.printStackTrace(); }finally { readWriteLock.writeLock().unlock(); } },String.valueOf(i)).start(); } //6个读者 for (int i = 0; i < 6; i++) { int num = i; new Thread(()->{ try { readWriteLock.readLock().lock(); String word = book.read(String.valueOf(num % 2)); System.out.println("读者"+num+"在阅读文章..."+word); } catch (Exception e) { e.printStackTrace(); } finally { readWriteLock.readLock().unlock(); } },String.valueOf(i)).start(); } } } class Book{ HashMap<String, String> map = new HashMap<>(); public void write(String key,String val){ map.put(key, val); } public String read(String key){ String word = map.get(key); return word; } }
輸出結果:
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=54141:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;E:\idea_workplace\javaBase\target\classes" 写手0在写文章 写手1在写文章 读者0在阅读文章...6b021 读者1在阅读文章...220e4 读者2在阅读文章...6b021 读者4在阅读文章...6b021 读者3在阅读文章...220e4 读者5在阅读文章...220e4 Process finished with exit code 0
讀取寫入鎖定的效率
(影片教學推薦:java影片教學)
讀寫鎖是否會提高使用互斥鎖的效能取決於資料被讀取的頻率與被修改的頻率,讀取和寫入操作的持續時間以及資料的爭用,嘗試同時讀取或寫入資料的執行緒數。
例如最初填入資料的集合,然後經常被修改的頻繁的搜尋(例如某種目錄)是使用讀寫鎖定的理想候選。然而,如果更新變得頻繁,那麼數據的大部分時間將被專門鎖定,並且並發性增加很少。
此外,如果讀取操作太短,則讀寫鎖定實作(其本身比互斥鎖更複雜)的開銷可以支配執行成本,特別是因為許多讀寫鎖定實作仍將序列化所有線程通過小部分代碼。最終,只有剖析和測量將確定使用讀寫鎖是否適合您的應用程式。
以上是什麼是讀寫鎖的詳細內容。更多資訊請關注PHP中文網其他相關文章!