zoukankan      html  css  js  c++  java
  • 读写锁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 }
    复制代码
  • 相关阅读:
    HDU 1813 Escape from Tetris
    BZOJ 2276 Temperature
    BZOJ 4499 线性函数
    BZOJ 3131 淘金
    HDU 5738 Eureka
    POJ 2409 Let it Bead
    POJ 1286 Necklace of Beads
    POJ 1696 Space Ant
    Fox And Jumping
    Recover the String
  • 原文地址:https://www.cnblogs.com/zhangyuhang3/p/6872664.html
Copyright © 2011-2022 走看看