讀寫各代表共享鎖和獨佔鎖
獨佔鎖:一個鎖只能被一個線程使用
共享鎖:一個鎖可被多個線程使用;讀鎖的共享鎖保證併發讀是非常高效的
package com.reentralock;
import java.util.HashMap;
class myCache{
private volatile HashMap<String, Object> map = new HashMap<>();//多線程保證map的可見性
public void put(String key,Object val){//模仿寫
System.out.println(Thread.currentThread().getName()+"\t writing...."+key);
map.put(key, val);
System.out.println(Thread.currentThread().getName()+"\t writed."+key);
}
public void get(String key){//模仿讀
System.out.println(Thread.currentThread().getName()+"\t reading...."+key);
map.get(key);
System.out.println(Thread.currentThread().getName()+"\t read over."+key);
}
}
/**
* 緩存機制:寫的時候保證開始寫和寫完之間不允許其他線程來寫,這就叫獨佔錯;但是讀的時候可以很多人來讀,這叫共享鎖;
* 如果對於redis緩存,你在寫的時候不允許別人來讀,redis你算什麼正經緩存!
* 也就是說在高併發場景下,我需要讀寫分離,而不是對於redis這塊內存空間來說,我在寫的時候我用ReentraLock鎖上,我沒寫完
* 其他線程b來讀我也不行,ReentrantReadWriteLock可以滿足只要我寫我的a,你讀你的b,是沒問題的
* @author 英俊
*
*/
public class ReentrantReadWriteLock {
public static void main(String[] args) {
myCache cache = new myCache();
for (int i = 0; i < 5; i++) {
final int ti = i;//lambda表達式中put必須是final級別的
new Thread(()->{
cache.put(ti+"", ti+"");
},"aa").start();
}
for (int i = 0; i < 5; i++) {
final int ti = i;
new Thread(()->{
cache.get(ti+"");
},"bb").start();
}
}
}
結果:寫的過程中,不允許其他操作進來,我在寫!不可以不原子。
我要使用讀(共享鎖)寫(獨佔鎖)鎖機制,提高的併發處理能力。
package com.reentralock;
import java.util.HashMap;
class myCache{
private volatile HashMap<String, Object> map = new HashMap<>();//多線程保證map的可見性
//讀寫鎖,用哪個找哪個
private java.util.concurrent.locks.ReentrantReadWriteLock lock = new java.util.concurrent.locks.ReentrantReadWriteLock();
public void put(String key,Object val){//模仿寫
//寫就獨佔鎖
lock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName()+"\t writing...."+key);
map.put(key, val);
System.out.println(Thread.currentThread().getName()+"\t writed."+key);
} finally {
lock.writeLock().unlock();
}
}
public void get(String key){//模仿讀
//讀就共享鎖
lock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName()+"\t reading...."+key);
map.get(key);
System.out.println(Thread.currentThread().getName()+"\t read over."+key);
} finally {
lock.readLock().unlock();
}
}
}
/**
* 緩存機制:寫的時候保證開始寫和寫完之間不允許其他線程來寫,這就叫獨佔錯;但是讀的時候可以很多人來讀,這叫共享鎖;
* 如果對於redis緩存,你在寫的時候不允許別人來讀,redis你算什麼正經緩存!
* 也就是說在高併發場景下,我需要讀寫分離,而不是對於redis這塊內存空間來說,我在寫的時候我用ReentraLock鎖上,我沒寫完
* 其他線程b來讀我也不行,ReentrantReadWriteLock可以滿足只要我寫我的a,你讀你的b,是沒問題的
* 目的:提高一致性和併發性。
* @author 英俊
*
*/
public class ReentrantReadWriteLock {
public static void main(String[] args) {
myCache cache = new myCache();
for (int i = 0; i < 5; i++) {
final int ti = i;//lambda表達式中put必須是final級別的
new Thread(()->{
cache.put(ti+"", ti+"");
},"aa").start();
}
for (int i = 0; i < 5; i++) {
final int ti = i;
new Thread(()->{
cache.get(ti+"");
},"bb").start();
}
}
}
結果: