请选择 进入手机版 | 继续访问电脑版
设为首页 收藏本站
开启辅助访问 切换到宽版

新浪微博登陆

只需一步, 快速开始

QQ登录

只需一步,快速开始

切换风格 立即注册 找回密码

Java教程网

新浪微博达人勋

3066

积分

805

帖子

748

贡献

Rank: 8Rank: 8

积分
3066

社区QQ达人

发表于 2017-3-7 19:49:06 | 显示全部楼层 |阅读模式
读写锁:多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥。即:读的时候不允许写,写的时候不允许读,可以同时读。
     synchronized关键字和普通的Lock构造的锁,会造成读与读之间的互斥,因此读写锁可提高性能。

例子1:三个线程同时对一个共享数据进行读写。
  1. import java.util.Random;
  2. import java.util.concurrent.locks.ReadWriteLock;
  3. import java.util.concurrent.locks.ReentrantReadWriteLock;

  4. public class ReadWriteLockTest {
  5.         public static void main(String[] args) {
  6.                final Queue queue = new Queue();
  7.                for (int i = 0; i < 3; i++) {
  8.                       new Thread() {
  9.                             public void run() {
  10.                                    while (true) {
  11.                                          queue.get();
  12.                                   }
  13.                            }

  14.                      }.start();

  15.                       new Thread() {
  16.                             public void run() {
  17.                                    while (true) {
  18.                                          queue.put( new Random().nextInt(10000));
  19.                                   }
  20.                            }

  21.                      }.start();
  22.               }

  23.        }
  24. }
复制代码
  1. class Queue {
  2.         PRivate Object data = null; // 共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。
  3.        ReadWriteLock rwl = new ReentrantReadWriteLock();

  4.         public void get() {
  5.                rwl.readLock().lock();
  6.                try {
  7.                      System. out.println(Thread.currentThread().getName() + " be ready to read data!");
  8.                      Thread. sleep((long) (Math. random() * 1000));
  9.                      System. out.println(Thread.currentThread().getName() + " have read data :" + data);
  10.               } catch (InterruptedException e) {
  11.                      e.printStackTrace();
  12.               } finally {
  13.                       rwl.readLock().unlock();
  14.               }
  15.        }

  16.         public void put(Object data) {

  17.                rwl.writeLock().lock();
  18.                try {
  19.                      System. out.println(Thread.currentThread().getName() + " be ready to write data!");
  20.                      Thread. sleep((long) (Math. random() * 1000));
  21.                       this.data = data;
  22.                      System. out.println(Thread.currentThread().getName() + " have write data: " + data);
  23.               } catch (InterruptedException e) {
  24.                      e.printStackTrace();
  25.               } finally {
  26.                       rwl.writeLock().unlock();
  27.               }

  28.        }
  29. }<span style="line-height: 1.5; background-color: rgb(255, 255, 255);"> </span>
复制代码


例子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. public class CacheDemo {

  6.         private static Map<String, Object> cache = new HashMap<String, Object>();

  7.         private ReadWriteLock rwl = new ReentrantReadWriteLock();

  8.         public Object getData(String key) {
  9.                // 当线程开始读时,首先开始加上读锁
  10.                rwl.readLock().lock();
  11.               Object value = null;
  12.                try {
  13.                      value = cache.get(key);
  14.                       // 判断是否存在值
  15.                       if (value == null) {
  16.                             // 在开始写之前,首先要释放读锁,否则写锁无法拿到
  17.                             rwl.readLock().unlock();
  18.                             // 获取写锁开始写数据
  19.                             rwl.writeLock().lock();
  20.                             try {
  21.                                    // 再次判断该值是否为空,因为如果两个写线程都阻塞在这里,
  22.                                    // 当一个线程被唤醒后value的值为null则进行数据加载,当另外一个线程也被唤醒如果不判断就会执行两次写  
  23.                                    if (value == null) {
  24.                                          value = "" ; // query 数据库
  25.                                           cache.put(key, value);
  26.                                   }
  27.                            } finally {
  28.                                    rwl.writeLock().unlock(); // 释放写锁
  29.                            }
  30.                             rwl.readLock().lock(); // 写完之后降级为读锁
  31.                      }
  32.               } finally {
  33.                       rwl.readLock().unlock(); // 释放读锁
  34.               }

  35.                return value;
  36.        }

  37. }
复制代码




来自群组: java开发组

新浪微博达人勋

2929

积分

734

帖子

731

贡献

Rank: 6Rank: 6

积分
2929
发表于 2017-3-7 19:49:48 | 显示全部楼层
报告!别开枪,我就是路过来看看的。。。

新浪微博达人勋

6430

积分

1606

帖子

1608

贡献

Rank: 8Rank: 8

积分
6430

社区QQ达人

发表于 2017-3-10 08:12:56 | 显示全部楼层
前排,哇咔咔

新浪微博达人勋

6614

积分

1652

帖子

1654

贡献

Rank: 8Rank: 8

积分
6614
发表于 2017-3-10 23:33:02 | 显示全部楼层
啊啊啊啊啊啊啊啊啊啊啊

新浪微博达人勋

3020

积分

756

帖子

754

贡献

Rank: 8Rank: 8

积分
3020
发表于 2017-3-11 13:54:16 | 显示全部楼层
打酱油的人拉,回复下赚取积分

新浪微博达人勋

2788

积分

697

帖子

697

贡献

Rank: 6Rank: 6

积分
2788

社区QQ达人最佳新人

发表于 2017-3-12 01:21:23 | 显示全部楼层
围观 围观 沙发在哪里!!!

新浪微博达人勋

6655

积分

1663

帖子

1664

贡献

Rank: 8Rank: 8

积分
6655
发表于 2017-3-14 08:50:30 | 显示全部楼层
是爷们的娘们的都帮顶!大力支持

新浪微博达人勋

6918

积分

1763

帖子

1701

贡献

Rank: 8Rank: 8

积分
6918

社区QQ达人最佳新人活跃会员热心会员

发表于 2017-3-17 17:37:44 | 显示全部楼层
珍爱生命,果断回帖。

新浪微博达人勋

6612

积分

1653

帖子

1653

贡献

Rank: 8Rank: 8

积分
6612
发表于 2017-3-18 05:43:05 | 显示全部楼层
:lol

新浪微博达人勋

6221

积分

1553

帖子

1556

贡献

Rank: 8Rank: 8

积分
6221
发表于 2017-3-22 19:23:17 | 显示全部楼层
站位支持
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

关闭

站长推荐 上一条 /1 下一条

小黑屋|手机版|Archiver|Java教程网    

GMT+8, 2019-5-27 19:36 , Processed in 0.343750 second(s), 40 queries .

Powered by Discuz X3.2

© 2001-2013 JAVA教程网

快速回复 返回顶部 返回列表