Java多线程学习笔记3——ReentranLock和ReentrantReadWriteLock

在java中实现的同步的方式有synchronized方法,synchronized代码块,ReentranLock,ReentrantReadWriteLock,

主要功能是在多线程的环境下实现代码的同步。

synchronized方法,有一定的局限性作用的区域受限,有时代码可能只需要方法中某一行或者几行代码要同步,不许要整个方法同步影响程序性能或则造成程序错误。这个时候可以使用synchronized代码块,而且代码块有更灵活的锁机制可以使用自定义的对象作为锁,也可以使用当前对象作为锁。下面对比下 lock 和  synchronized:

1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;

2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现发象生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;

3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;

4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。

5)Lock可以提高多个线程进行读操作的效率。

 ReentrantReadWriteLock更是可以对读写两种不同的情况分别加锁。具体情景如下:写的时候不能读取数据,而且写之间是互斥的,读的时候不互斥。代码如下:

public class ReadWriterLock {
	public static void main(String[] args) {
		final Queue3 q3 = new Queue3();
		for (int i = 0; i < 3; i++) {
			new Thread() {
				public void run() {
					while (true) {
						q3.get();
					}
				};
			}.start();
			new Thread() {
				public void run() {
					while (true) {
						q3.put(new Random().nextInt(10000));
					}
				};
			}.start();
		}
	}
}
class Queue3 {
	private Object data = 0;
	private ReadWriteLock rwL = new ReentrantReadWriteLock();
	public  void get() {
		rwL.readLock().lock();
		try {
			System.out.println(Thread.currentThread().getName() + " ready   read   data!");
			Thread.sleep((long) (Math.random() * 1000));
			System.out.println(Thread.currentThread().getName() + "have   read   data!"+this.data.toString());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			rwL.readLock().unlock();
		}	
	}
	public void put(Object data) {
		rwL.writeLock().lock();
		try {
			System.out.println(Thread.currentThread().getName() + " ready  write data!");
			this.data = data;
			Thread.sleep((long) (Math.random() * 1000));
			System.out.println(Thread.currentThread().getName() + "have  write  data!"+this.data.toString());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			rwL.writeLock().unlock();
		}
	}
}

以上实现了写和读之间的互斥。使用此特点可以设计一个缓存系统:代码如下

ConcurrentHashMap<String, String>  hashMap=new  ConcurrentHashMap<>(); 
	
	public String get(String key){
		ReadWriteLock  readWriteLock=new ReentrantReadWriteLock();
		readWriteLock.readLock().lock();
		if(hashMap.containsKey(key)){
			return hashMap.get(key);
		}else{
			readWriteLock.readLock().unlock();
			readWriteLock.writeLock().lock();
			String  db=null;
			if(!hashMap.containsKey(key)){
			    db=new Random()+"123aaa";
				hashMap.put(key,db);
			}
			readWriteLock.writeLock().unlock();
			return db;
		}
	}


猜你喜欢

转载自blog.csdn.net/zhangkang65/article/details/79414557