读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!
三个线程读数据,三个线程写数据示例:
可以同时读,读的时候不能写,不能同时写,写的时候不能读。
读的时候上读锁,读完解锁;写的时候上写锁,写完解锁。
注意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;//共享数据,只能有一个线程写该数据,但可以有多个线程同时读该数据。
readwritelock rwl = new reentrantreadwritelock();
/**
* 读数据
*/
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();
}
}
/**
* 写数据
*
* @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();
}
}
}
设计一个缓存系统
缓存系统:你要取数据,需调用我的public object getdata(string key)方法,我要检查我内部有没有这个数据,如果有就直接返回,如果没有,就从数据库中查找这个数,查到后将这个数据存入我内部的存储器中,下次再有人来要这个数据,我就直接返回这个数不用再到数据库中找了。你要取数据不要找数据库,来找我。
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;
/**
* 设计一个缓存系统
*
*
* @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)); //从数据库获取数据
system.out.println(cachedemo.getdata(key)); //从缓存获取数据
system.out.println(cachedemo.getdata(key)); //从缓存获取数据
}
private readwritelock rwl = new reentrantreadwritelock();
public object getdata(string key) {
rwl.readlock().lock(); //上读锁
object value = null;
try {
value = cache.get(key); //先查询内部存储器中有没有要的值
if (value == null) { //如果没有,就去数据库中查询,并将查到的结果存入内部存储器中
//释放读锁、上写锁
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();
}
//恢复读写状态
rwl.readlock().lock();
}else{
system.out.println("read data from cache");
}
} finally {
rwl.readlock().unlock(); //释放读锁
}
return value;
}
}
更多java多线程编程之读写锁readwritelock用法实例。