`

ReentrantReadWriteLock

 
阅读更多

多线程中对某些共享变量进行读写操作,并发读操作时不会产生问题,并发读写或并发写操作会引起线程安全性问题。

下面代码会报错:java.util.ConcurrentModificationException

 

public class TestReentrantReadWriteLock {
	volatile Map dataMap = new HashMap();
	private static TestReentrantReadWriteLock  testReentraintReadWriteLock = new TestReentrantReadWriteLock();
	private static TestReentrantReadWriteLock getInstace(){
		return testReentraintReadWriteLock;
	}
	public void  readMap(){
		Map refMap = dataMap;
		Iterator iterator = refMap.keySet().iterator();
		while(iterator.hasNext()){//这行报错:java.util.ConcurrentModificationException
			Object key = iterator.next();
			Object value = refMap.get(key);
		}
	}
	public void writeMap(){
		dataMap.clear();
		for(int i=0;i<100;i++){
			dataMap.put(i+"", i+"");
		}
	}

	public static void main(String args []){
		for(int i=0;i<2;i++){
			new Thread(new Runnable(){
				@Override
				public void run() {
					// TODO Auto-generated method stub\
					while(true){
						TestReentrantReadWriteLock.getInstace().readMap();
					}
				}
			}).start();
		}
		for(int i=0;i<1;i++){
			new Thread(new Runnable(){
				@Override
				public void run() {
					while(true){
						TestReentrantReadWriteLock.getInstace().writeMap();
					}
				}
			}).start();
		}
	}
}

解决方法:

 

1 如果只有一条线程会执行写操作, 可以在写操作时新建一个MAP(业务逻辑上可行的话),然后替换原来的MAP:

   

	public void writeMap(){
		Map newMap = new HashMap();
		
		for(int i=0;i<100;i++){
			newMap.put(i+"", i+"");
		}
		dataMap = newMap;
	}

 

1.使用java.util.concurrent.ConcurrentHashMap 代替HashMap 解决问题。 

 2.使用synchronized 锁,需要加到 writeMap 和 readMap方法上,可以决问题,但多个读操作互斥,影响并发。

3.读操作远大于写操作情况下可以使用ReentrantReadWriteLock

  示例代码:

ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
	public void  readMap(){
		rwl.readLock().lock();//读取锁    读取与读取可并发,与写入互斥
		try{
			Map refMap = dataMap;
			Iterator iterator = refMap.keySet().iterator();
			while(iterator.hasNext()){
				Object key = iterator.next();
				Object value = refMap.get(key);
			}
		}finally{
			rwl.readLock().unlock();//解锁
		}
	}
	public void writeMap(){
		rwl.writeLock().lock();//写入锁  写入与读取之间互斥        写入与写入之间互斥
		try{
			dataMap.clear();
			for(int i=0;i<100;i++){
				dataMap.put(i+"", i+"");//解锁
			}
		
		}finally{
			rwl.writeLock().unlock();
		}
	}

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics