java實現(xiàn)ReadWriteLock讀寫鎖的示例
讀寫鎖基本概念
ReadWriteLock是Java并發(fā)包中的一個接口,它定義了兩種鎖:讀鎖(Read Lock)和寫鎖(Write Lock),真正的實現(xiàn)類是ReentrantReadWriteLock。讀鎖允許多個線程同時讀取共享資源,而寫鎖則要求獨占資源,即當一個線程持有寫鎖時,其他線程不能獲取讀鎖或?qū)戞i。
讀寫鎖的作用
在進行共享資源的并發(fā)訪問時,不論是使用synchronized還是使用重入鎖ReentrantLock,一次都只允許一個線程訪問共享資源,但是很多時候我們只是要讀取共享資源,并不修改共享資源,多個線程同時讀取共享資源并不會產(chǎn)生不一致問題,而且還能提高并發(fā)效率,對共享資源修改時就只讓一個線程進入,又保證數(shù)據(jù)的一致性,這就是讀寫鎖ReadWriteLock誕生的原因。讀寫鎖分離是一種常見的鎖思想。例如在一些數(shù)據(jù)庫內(nèi),利用讀鎖讓多個事務可以同時讀某行數(shù)據(jù),并且數(shù)據(jù)不會被修改,利用寫鎖保證只有一個事務可以修改某行數(shù)據(jù),并且不會被其它事務讀取到臟數(shù)據(jù)。
寫鎖:也叫作排他鎖,如果數(shù)據(jù)有加寫鎖,就只有持有寫鎖的線程才能對數(shù)據(jù)進行操作,數(shù)據(jù)加持著寫鎖時,其他線程不能加寫鎖,也不能施加讀鎖。
讀鎖:也叫作共享鎖,多個線程可以對同一個數(shù)據(jù)添加多個讀鎖,數(shù)據(jù)被加上讀鎖后就不能再被加上寫鎖。
讀寫鎖的使用
使用ReadWriteLock實現(xiàn)讀寫控制示例:
import java.util.concurrent.CountDownLatch; import java.util.concurrent.locks.ReentrantReadWriteLock; public class RWLock { public static final CountDownLatch countDownLatch = new CountDownLatch(10); public static final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); //獲取讀鎖 public static final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock(); //獲取寫鎖 public static final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock(); public static void main(String[] args) throws InterruptedException { long start = System.currentTimeMillis(); //8個線程模擬讀操作 for (int i = 0; i < 8; i++) { new Thread(() -> { readLock.lock(); try { Thread.sleep(1000); // 模擬讀操作 countDownLatch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } finally { readLock.unlock(); } }).start(); } //2個線程模擬寫操作 for (int i = 0; i < 2; i++) { new Thread(() -> { writeLock.lock(); try { Thread.sleep(2000); // 模擬寫操作 countDownLatch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } finally { writeLock.unlock(); } }).start(); } //等待所有操作完成 countDownLatch.await(); long end = System.currentTimeMillis(); System.out.println("任務完成,耗時:" + (end - start)); } } //任務完成,耗時:3081
使用ReentrantLock實現(xiàn)讀寫控制示例:
import java.util.concurrent.CountDownLatch; import java.util.concurrent.locks.ReentrantLock; public class RWLock { public static final CountDownLatch countDownLatch = new CountDownLatch(10); public static final ReentrantLock lock = new ReentrantLock(); public static void main(String[] args) throws InterruptedException { long start = System.currentTimeMillis(); for (int i = 0; i < 10; i++) { new Thread(() -> { lock.lock(); try { Thread.sleep(1000); // 模擬讀操作 countDownLatch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } }).start(); } //等待所有操作完成 countDownLatch.await(); long end = System.currentTimeMillis(); System.out.println("任務完成,耗時:" + (end - start)); } } //任務完成,耗時:10155
以上兩個示例中,使用ReadWriteLock實現(xiàn)的讀寫控制任務總耗時3秒左右,而使用ReentrantLock的實現(xiàn)的讀寫控制任務總耗時10秒左右,在這個例子中ReadWriteLock比ReentrantLock快了3倍多,這是否就意味著ReadWriteLock的性能就一定比ReentrantLock好呢?其實不是的,ReadWriteLock適用于讀多寫少的場景,如上面例子中使用了8個線程模擬讀操作,2個線程模擬寫操作就是讀多寫少的場景,在寫操作密集的場景下ReadWriteLock的復雜性使它具有更大的鎖開銷。應該在不同的場景下選擇合適的鎖。
到此這篇關于java實現(xiàn)ReadWriteLock讀寫鎖的示例的文章就介紹到這了,更多相關java ReadWriteLock讀寫鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
springboot3.4和mybatis plus的版本問題的解決
本文主要介紹了springboot3.4和mybatis plus的版本問題的解決,主要由于Spring Boot 3.4與MyBatis-Plus版本不匹配導致分頁功能問題,下面就來解決這個問題,感興趣的可以了解一下2025-03-03Java多線程中ReentrantLock與Condition詳解
這篇文章主要介紹了Java多線程中ReentrantLock與Condition詳解,需要的朋友可以參考下2017-11-11springboot 加載 META-INF/spring.factories方式
這篇文章主要介紹了springboot 加載 META-INF/spring.factories方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10SpringBoot自定義注解使用讀寫分離Mysql數(shù)據(jù)庫的實例教程
這篇文章主要給大家介紹了關于SpringBoot自定義注解使用讀寫分離Mysql數(shù)據(jù)庫的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11SpringBoot結合ProGuard實現(xiàn)代碼混淆(最新版)
這篇文章主要介紹了SpringBoot結合ProGuard實現(xiàn)代碼混淆(最新版),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-10-10