读写锁ReadWriteLock和缓存实例


读写锁:多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥。即:读的时候不允许写,写的时候不允许读,可以同时读。     synchronized关键字和普通的Lock构造的锁,会造成读与读之间的互斥,因此读写锁可提高性能。 例子1:三个线程同时对一个共享数据进行读写。 
 1 import java.util.Random;
2 import java.util.concurrent.locks.ReadWriteLock;
3 import java.util.concurrent.locks.ReentrantReadWriteLock;
4
5 public class ReadWriteLockTest {
6 public static void main(String[] args) {
7 final Queue queue = new Queue();
8 for (int i = 0; i < 3; i++) {
9 new Thread() {
10 public void run() {
11 while (true) {
12 queue.get();
13 }
14 }
15
16 }.start();
17
18 new Thread() {
19 public void run() {
20 while (true) {
21 queue.put( new Random().nextInt(10000));
22 }
23 }
24
25 }.start();
26 }
27
28 }
29 }
30
31 class Queue {
32 private Object data = null; // 共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。
33 ReadWriteLock rwl = new ReentrantReadWriteLock();
34
35 public void get() {
36 rwl.readLock().lock();
37 try {
38 System. out.println(Thread.currentThread().getName() + " be ready to read data!");
39 Thread. sleep((long) (Math. random() * 1000));
40 System. out.println(Thread.currentThread().getName() + " have read data :" + data);
41 } catch (InterruptedException e) {
42 e.printStackTrace();
43 } finally {
44 rwl.readLock().unlock();
45 }
46 }
47
48 public void put(Object data) {
49
50 rwl.writeLock().lock();
51 try {
52 System. out.println(Thread.currentThread().getName() + " be ready to write data!");
53 Thread. sleep((long) (Math. random() * 1000));
54 this.data = data;
55 System. out.println(Thread.currentThread().getName() + " have write data: " + data);
56 } catch (InterruptedException e) {
57 e.printStackTrace();
58 } finally {
59 rwl.writeLock().unlock();
60 }
61
62 }
63 }

 

例子2:缓存实例
 1 import java.util.HashMap;
2 import java.util.Map;
3 import java.util.concurrent.locks.ReadWriteLock;
4 import java.util.concurrent.locks.ReentrantReadWriteLock;
5
6 public class CacheDemo {
7
8 private static Map<String, Object> cache = new HashMap<String, Object>();
9
10 private ReadWriteLock rwl = new ReentrantReadWriteLock();
11
12 public Object getData(String key) {
13 // 当线程开始读时,首先开始加上读锁
14 rwl.readLock().lock();
15 Object value = null;
16 try {
17 value = cache.get(key);
18 // 判断是否存在值
19 if (value == null) {
20 // 在开始写之前,首先要释放读锁,否则写锁无法拿到
21 rwl.readLock().unlock();
22 // 获取写锁开始写数据
23 rwl.writeLock().lock();
24 try {
25 // 再次判断该值是否为空,因为如果两个写线程都阻塞在这里,
26 // 当一个线程被唤醒后value的值为null则进行数据加载,当另外一个线程也被唤醒如果不判断就会执行两次写
27 if (value == null) {
28 value = "" ; // query 数据库
29 cache.put(key, value);
30 }
31 } finally {
32 rwl.writeLock().unlock(); // 释放写锁
33 }
34 rwl.readLock().lock(); // 写完之后降级为读锁
35 }
36 } finally {
37 rwl.readLock().unlock(); // 释放读锁
38 }
39
40 return value;
41 }
42
43 }

 

本站声明
本文转载自:http://www.cnblogs.com/tstd/p/5040260.html     作者:吞噬天帝     发布日期:2015/12/11     本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。


 
© 2014-2017 ITdaan.com 粤ICP备14056181号