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 }
  • 相关阅读:
    idea连接数据库和版本控制(Version Control)
    Idea新手入门-部署tomcat
    Redis 列表(List)
    Redis 集合(Set)
    Redis中的哈希(Hash)
    Redis初步整理
    C#中的集合之ArryList
    linux中pip安装步骤与使用详解
    搭建 LAMP 环境
    搭建WordPress 个人博客
  • 原文地址:https://www.cnblogs.com/tstd/p/5040260.html
Copyright © 2011-2022 走看看