Java多線程編程之讀寫鎖ReadWriteLock用法實例
讀寫鎖:分為讀鎖和寫鎖,多個讀鎖不互斥,讀鎖與寫鎖互斥,這是由jvm自己控制的,你只要上好相應的鎖即可。如果你的代碼只讀數(shù)據(jù),可以很多人同時讀,但不能同時寫,那就上讀鎖;如果你的代碼修改數(shù)據(jù),只能有一個人在寫,且不能同時讀取,那就上寫鎖??傊?,讀的時候上讀鎖,寫的時候上寫鎖!
三個線程讀數(shù)據(jù),三個線程寫數(shù)據(jù)示例:
可以同時讀,讀的時候不能寫,不能同時寫,寫的時候不能讀。
讀的時候上讀鎖,讀完解鎖;寫的時候上寫鎖,寫完解鎖。
注意finally解鎖。
package com.ljq.test.thread;
import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 讀寫鎖
*
* @author Administrator
*
*/
public class ReadWriteLockTest {
public static void main(String[] args) {
final ReadWrite rw = new ReadWrite();
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
while (true) {
rw.read();
}
}
}.start();
new Thread() {
public void run() {
while (true) {
rw.write(new Random().nextInt(10000));
}
}
}.start();
}
}
}
/**
* 讀和寫要互斥,因此要把它們放在同一個類中
*
* @author Administrator
*
*/
class ReadWrite {
private Object data = null;//共享數(shù)據(jù),只能有一個線程寫該數(shù)據(jù),但可以有多個線程同時讀該數(shù)據(jù)。
ReadWriteLock rwl = new ReentrantReadWriteLock();
/**
* 讀數(shù)據(jù)
*/
public void read() {
rwl.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " be ready to read data!");
Thread.sleep((long) (Math.random() * 1000));
System.out.println(Thread.currentThread().getName() + "have read data :" + data);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
rwl.readLock().unlock();
}
}
/**
* 寫數(shù)據(jù)
*
* @param data
*/
public void write(Object data) {
rwl.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " be ready to write data!");
Thread.sleep((long) (Math.random() * 1000));
this.data = data;
System.out.println(Thread.currentThread().getName() + " have write data: " + data);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
rwl.writeLock().unlock();
}
}
}
設計一個緩存系統(tǒng)
緩存系統(tǒng):你要取數(shù)據(jù),需調用我的public Object getData(String key)方法,我要檢查我內部有沒有這個數(shù)據(jù),如果有就直接返回,如果沒有,就從數(shù)據(jù)庫中查找這個數(shù),查到后將這個數(shù)據(jù)存入我內部的存儲器中,下次再有人來要這個數(shù)據(jù),我就直接返回這個數(shù)不用再到數(shù)據(jù)庫中找了。你要取數(shù)據(jù)不要找數(shù)據(jù)庫,來找我。
package com.ljq.test.thread;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 設計一個緩存系統(tǒng)
*
*
* @author Administrator
*
*/
public class CacheDemo {
private Map<String, Object> cache = new HashMap<String, Object>();
public static void main(String[] args) {
String key = "name";
CacheDemo cacheDemo = new CacheDemo();
System.out.println(cacheDemo.getData(key)); //從數(shù)據(jù)庫獲取數(shù)據(jù)
System.out.println(cacheDemo.getData(key)); //從緩存獲取數(shù)據(jù)
System.out.println(cacheDemo.getData(key)); //從緩存獲取數(shù)據(jù)
}
private ReadWriteLock rwl = new ReentrantReadWriteLock();
public Object getData(String key) {
rwl.readLock().lock(); //上讀鎖
Object value = null;
try {
value = cache.get(key); //先查詢內部存儲器中有沒有要的值
if (value == null) { //如果沒有,就去數(shù)據(jù)庫中查詢,并將查到的結果存入內部存儲器中
//釋放讀鎖、上寫鎖
rwl.readLock().unlock();
rwl.writeLock().lock();
try {
if (value == null) { //再次進行判斷,防止多個寫線程堵在這個地方重復寫
System.out.println("read data from database");
value = "張三";
cache.put(key, value);
}
} finally {
//設置完成 釋放寫鎖
rwl.writeLock().unlock();
}
//恢復讀寫狀態(tài)
rwl.readLock().lock();
}else{
System.out.println("read data from cache");
}
} finally {
rwl.readLock().unlock(); //釋放讀鎖
}
return value;
}
}
返回結果:

相關文章
mybatis簡介與配置_動力節(jié)點Java學院整理
這篇文章主要介紹了mybatis簡介與配置,介紹了MyBatis+Spring+MySql簡單配置,有興趣的可以了解一下2017-09-09
spring的構造函數(shù)注入屬性@ConstructorBinding用法
這篇文章主要介紹了關于spring的構造函數(shù)注入屬性@ConstructorBinding用法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
SpringBoot使用easy-captcha 實現(xiàn)驗證碼登錄功能(解決思路)
文章介紹了如何使用Spring Boot和Easy-Captcha實現(xiàn)驗證碼登錄功能,后端通過Easy-Captcha生成驗證碼并存儲在Redis中,前端獲取驗證碼并顯示給用戶,登錄時,前端將用戶輸入的驗證碼和標識符發(fā)送到后端進行驗證,感興趣的朋友跟隨小編一起看看吧2025-02-02
MyBatis創(chuàng)建存儲過程的實例代碼_動力節(jié)點Java學院整理
本節(jié)需要用到的有2部分,第一部分是如何在Derby中創(chuàng)建存儲過程,第二部分是如何在Mybatis中調用存儲過程,具體實例代碼大家參考下本文吧2017-09-09
JAVA基礎類庫之String類,StringBuffer類和StringBuilder類
這篇文章主要介紹了Java中基礎類庫的String類,StringBuffer類和StringBuilder類,是Java入門學習中的基礎知識,需要的朋友可以參考下2021-09-09

