读写锁应用实例(ReentrantReadWriteLock)及
2017-02-08 本文已影响48人
higher2017
以下知识参考至《Java并发编程的艺术》
这里使用的是读写锁:ReentrantReadWriteLock
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Cache {
static Map<String,Object> map = new HashMap<String, Object>();
static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
static Lock readLock = readWriteLock.readLock();
static Lock writeLock = readWriteLock.writeLock();
public static final Object getByKey(String key){
readLock.lock();
try{
return map.get(key);
}finally{
readLock.unlock();
}
}
public static final Object getMap(){
readLock.lock();
try{
return map;
}finally{
readLock.unlock();
}
}
public static final Object put(String key,Object value){
writeLock.lock();
try{
return map.put(key, value);
}finally{
writeLock.unlock();
}
}
public static final Object remove(String key){
writeLock.lock();
try{
return map.remove(key);
}finally{
writeLock.unlock();
}
}
public static final void clear(){
writeLock.lock();
try{
map.clear();
}finally{
writeLock.unlock();
}
}
public static void main(String[] args) {
List<Thread> threadList = new ArrayList<Thread>();
for(int i =0;i<6;i++){
Thread thread = new PutThread();
threadList.add(thread);
}
for(Thread thread : threadList){
thread.start();
}
put("ji","ji");
System.out.println(getMap());
}
//上面的代码我在测试的时候居然出现了java.util.ConcurrentModificationException异常,请问有没有大神能够解答
private static class PutThread extends Thread{
public void run(){
put(Thread.currentThread().getName(),Thread.currentThread().getName());
}
}
}
在Java5之前我们一般这样去实现:
import java.util.HashMap;
import java.util.Map;
public class CacheSyn {
static Map<String, Object> map = new HashMap<String, Object>();
private static final String mapLockStr = "mapLockStr";
public static final Object getByKey(String key) {
//以字符串mapLockStr为锁
synchronized(mapLockStr.intern()){
return map.get(key);
}
}
public static final Object getMap() {
synchronized(mapLockStr.intern()){
return map;
}
}
public static final Object put(String key, Object value) {
synchronized(mapLockStr.intern()){
return map.put(key, value);
}
}
public static final Object remove(String key) {
synchronized(mapLockStr.intern()){
return map.remove(key);
}
}
public static final void clear() {
synchronized(mapLockStr.intern()){
map.clear();
}
}
public static void main(String[] args) {
List<Thread> threadList = new ArrayList<Thread>();
for(int i =0;i<6;i++){
Thread thread = new PutThread();
threadList.add(thread);
}
for(Thread thread : threadList){
thread.start();
}
put("ji", "ji");
System.out.println(getMap());
}
private static class PutThread extends Thread {
public void run() {
put(Thread.currentThread().getName(), Thread.currentThread().getName());
}
}
}
//上面的代码我在测试的时候居然出现了java.util.ConcurrentModificationException异常,请问有没有大神能够解答
在锁的获取上:
1、读写锁(其实Lock的实现类都一样):都需要通过调用lock()方法来显示获取锁,并且在使用完之后也要调用unlock()方法显示释放锁,获取和释放都是主动的过程。注意:如果在调用unlock()方法之前方法就抛出异常,锁将无法释放建议锁的释放放在finally代码块中执行
2、Synchronized:这里我是使用同步代码块的形式实现同步的,当进入某个Synchronized(object)修饰的代码块之前,该对象必须要获得object这个锁对象,才能进去向下执行,而且一次只能进一个。代码块执行完毕,锁会自动释放。
性能比较:
- 当没有写操作时,ReentrantReadWriteLock方式允许同一时间多个线程读取。而Synchronized方式却不行,所以在并发性能上ReentrantReadWriteLock更优。
- ReentrantReadWriteLock方式相较于Synchronized方式的等待通知机制实现方式更加明了。