java读写锁
程序员文章站
2022-05-04 17:17:25
...
读写锁
假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写(译者注:也就是说:读-读能共存,读-写不能共存,写-写不能共存)。这就需要一个读/写锁来解决这个问题。Java5在java.util.concurrent包中已经包含了读写锁。尽管如此,我们还是应该了解其实现背后的原理。
这里有个小例子,就是让写入的时候,不要出现读,我们模拟一个cache的一个缓冲例子:
package com.newDemo.controller.test;
import java.util.HashMap;
import java.util.Map;
public class threadDemo28 {
static Map<String, Object> map = new HashMap<String, Object>();
// 获取一个key对应的value
public static final Object get(String key) {
System.out.println("正在做读的操作,key:" + key + " 开始");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Object object = map.get(key);
System.out.println("正在做读的操作,key:" + key + " 结束");
System.out.println();
return object;
}
// 设置key对应的value,并返回旧有的value
public static final Object put(String key, Object value) {
System.out.println("正在做写的操作,key:" + key + ",value:" + value + "开始.");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Object object = map.put(key, value);
System.out.println("正在做写的操作,key:" + key + ",value:" + value + "结束.");
System.out.println();
return object;
}
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
threadDemo28.put(i + "", i + "");
}
}
}).start();
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
threadDemo28.get(i + "");
}
}
}).start();
}
}
效果如下:
这个地方就出现了在写的时候,有读的现象。所以说我们用读写锁ReentrantReadWriteLock。
package com.newDemo.controller.test;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class threadDemo29 {
static Map<String, Object> map = new HashMap<String, Object>();
static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
static Lock r = rwl.readLock();
static Lock w = rwl.writeLock();
// 获取一个key对应的value
public static final Object get(String key) {
Object object = null;
try {
r.lock();
System.out.println("正在做读的操作,key:" + key + " 开始");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
object = map.get(key);
System.out.println("正在做读的操作,key:" + key + " 结束");
System.out.println();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
r.unlock();
}
return object;
}
// 设置key对应的value,并返回旧有的value
public static final Object put(String key, Object value) {
Object object = null;
try {
w.lock();
System.out.println("正在做写的操作,key:" + key + ",value:" + value + "开始.");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
object = map.put(key, value);
System.out.println("正在做写的操作,key:" + key + ",value:" + value + "结束.");
System.out.println();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
w.unlock();
}
return object;
}
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
threadDemo29.put(i + "", i + "");
}
}
}).start();
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
threadDemo29.get(i + "");
}
}
}).start();
}
}
结果如下:
这个地方就是读写分离了,保证了线程的安全性。
上一篇: WEEK5 作业 D - 滑动窗口