在上文中提到了Lock接口以及对象,使用它,很优雅的控制了竞争资源的安全访问,但是这种锁不区分读写,称这种锁为普通锁。为了提高性能,Java提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控制,在一定程度上提高了程序的执行效率。

在上文中提到了Lock接口以及对象,使用它,很优雅的控制了竞争资源的安全访问,但是这种锁不区分读写,称这种锁为普通锁。为了提高性能,Java提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控制,在一定程度上提高了程序的执行效率。

Java中读写锁有个接口java.util.concurrent.locks.ReadWriteLock,也有具体的实现ReentrantReadWriteLock,详细的API可以查看JavaAPI文档。

下面这个例子是在文例子的基础上,将普通锁改为读写锁,并添加账户余额查询的功能,代码如下:

package cn.thread;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;/*** 读写锁* * @author 林计钦* @version 1.0 2013-7-25 上午10:33:37*/
public class WriteReadLockTest {public static void main(String[] args) {WriteReadLockTest test = new WriteReadLockTest();// 创建并发访问的账户MyCount myCount = test.new MyCount("95599200901215522", 10000);// 创建一个锁对象ReadWriteLock lock = new ReentrantReadWriteLock(false);// 创建一个线程池ExecutorService pool = Executors.newFixedThreadPool(2);// 创建一些并发访问用户,一个信用卡,存的存,取的取,好热闹啊User u1 = test.new User("张三", myCount, -4000, lock, false);User u2 = test.new User("张三他爹", myCount, 6000, lock, false);User u3 = test.new User("张三他弟", myCount, -8000, lock, false);User u4 = test.new User("张三", myCount, 800, lock, false);User u5 = test.new User("张三他爹", myCount, 0, lock, true);// 在线程池中执行各个用户的操作pool.execute(u1);pool.execute(u2);pool.execute(u3);pool.execute(u4);pool.execute(u5);// 关闭线程池pool.shutdown();}/*** 信用卡的用户*/class User implements Runnable {private String name; // 用户名private MyCount myCount; // 所要操作的账户private int iocash; // 操作的金额,当然有正负之分了private ReadWriteLock myLock; // 执行操作所需的锁对象private boolean ischeck; // 是否查询User(String name, MyCount myCount, int iocash, ReadWriteLock myLock, boolean ischeck) {this.name = name;this.myCount = myCount;this.iocash = iocash;this.myLock = myLock;this.ischeck = ischeck;}public void run() {if (ischeck) {// 获取读锁myLock.readLock().lock();System.out.println("读:" + name + "正在查询" + myCount + "账户,当前金额为" + myCount.getCash());// 释放读锁myLock.readLock().unlock();} else {// 获取写锁myLock.writeLock().lock();// 执行现金业务System.out.println("写:" + name + "正在操作" + myCount + "账户,金额为" + iocash + ",当前金额为"+ myCount.getCash());myCount.setCash(myCount.getCash() + iocash);System.out.println("写:" + name + "操作" + myCount + "账户成功,金额为" + iocash + ",当前金额为"+ myCount.getCash());// 释放写锁myLock.writeLock().unlock();}}}/*** 信用卡账户,可随意透支*/class MyCount {private String oid; // 账号private int cash; // 账户余额MyCount(String oid, int cash) {this.oid = oid;this.cash = cash;}public String getOid() {return oid;}public void setOid(String oid) {this.oid = oid;}public int getCash() {return cash;}public void setCash(int cash) {this.cash = cash;}@Overridepublic String toString() {return "MyCount{" + "oid='" + oid + '\'' + ", cash=" + cash + '}';}}
}

写:张三正在操作MyCount{oid='95599200901215522', cash=10000}账户,金额为-4000,当前金额为10000
写:张三操作MyCount{oid='95599200901215522', cash=6000}账户成功,金额为-4000,当前金额为6000
写:张三他爹正在操作MyCount{oid='95599200901215522', cash=6000}账户,金额为6000,当前金额为6000
写:张三他爹操作MyCount{oid='95599200901215522', cash=12000}账户成功,金额为6000,当前金额为12000
写:张三正在操作MyCount{oid='95599200901215522', cash=12000}账户,金额为800,当前金额为12000
写:张三操作MyCount{oid='95599200901215522', cash=12800}账户成功,金额为800,当前金额为12800
写:张三他弟正在操作MyCount{oid='95599200901215522', cash=12800}账户,金额为-8000,当前金额为12800
写:张三他弟操作MyCount{oid='95599200901215522', cash=4800}账户成功,金额为-8000,当前金额为4800
读:张三他爹正在查询MyCount{oid='95599200901215522', cash=4800}账户,当前金额为4800

在实际开发中,最好在能用读写锁的情况下使用读写锁,而不要用普通锁,以求更好的性能。

本文转自:http://www.cnblogs.com/linjiqin/p/3214023.html 感谢作者

Java多线程-新特征-锁(下)相关推荐

  1. java check word lock_Java多线程-新特征-锁(下)

    在上文中提到了Lock接口以及对象,使用它,很优雅的控制了竞争资源的安全访问,但是这种锁不区分读写,称这种锁为普通锁.为了提高性能,Java提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控 ...

  2. Java多线程-新特征-阻塞队列ArrayBlockingQueue

    阻塞队列是Java5线程新特征中的内容,Java定义了阻塞队列的接口java.util.concurrent.BlockingQueue,阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素 ...

  3. Java 多线程 不使用锁机制 实现交替打印数字和字母

    Java 多线程 不使用锁机制 实现交替打印数字和字母 这是一道经典的面试题,使用两个线程去交替打印数字和字母,输出1A2B3C4D5E6F7G-这样的效果,看了网上很多的文章,基本都是使用Condi ...

  4. Java多线程系列--“JUC锁”05之 非公平锁

    转载自:http://www.cnblogs.com/skywang12345/p/3496651.html点击打开链接 概要 前面两章分析了"公平锁的获取和释放机制",这一章开始 ...

  5. Java多线程系列---“JUC锁”01之 框架

    本章,我们介绍锁的架构:后面的章节将会对它们逐个进行分析介绍.目录如下: 01. Java多线程系列--"JUC锁"01之 框架 02. Java多线程系列--"JUC锁 ...

  6. Java多线程系列--“JUC锁”03之 公平锁(一)

    概要 本章对"公平锁"的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括: 基本概念 ReentrantLock数据结构 参考代码 获取公平锁(基于JDK1.7.0 ...

  7. 教练, 我想学java的新特征

    java的新特征

  8. Java线程新特征——Java并发库

    一.线程池   Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定 ...

  9. Java多线程-新特性-线程池

    Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定可靠的多线程程序 ...

  10. Java多线程中的锁

    死锁.活锁.饥饿是关于多线程是否活跃.出现的运行阻塞障碍问题,如果线程出现了这三种情况,即线程不再活跃,不能再正常地执行下去 死锁 死锁是多线程中最差的一种情况,多个线程相互占用对方的资源锁,而又相互 ...

最新文章

  1. 用ABAP代码读取S/4HANA生产订单工序明细
  2. SSH开发环境整合搭建
  3. 基于Xml 的IOC 容器-载入<list>的子元素
  4. 多线程与高并发(九):单机压测工具JMH,单机最快MQ - Disruptor原理解析
  5. 从一本书看经济危机中创业者的机会
  6. 多通道_人机交互界面的多通道RGB LED驱动设计
  7. 英语中十二个月名称的由来
  8. 1.5 编程基础之循环控制 11 整数的个数(2022.01.09)--python
  9. [最短路/线段树大法优化DIJ] 【模板】单源最短路径(标准版)
  10. 在RedHat Enterprise Linux 上Oracle 9i的安装配置与调优
  11. unity3D android游戏屏幕分辨率问题【转http://blog.csdn.net/jeksonal/article/details/8501549】...
  12. 如何使用jMeter对某个OData服务进行高并发性能测试
  13. 【Vue】postman汉化教程 保姆级教程 包教会
  14. 迅雷没有做错什么,只是用户不需要了
  15. 老外用VB6写的Windows驱动备份软件
  16. HMC5883L校准
  17. python卡方检验kf_Python 卡方检验
  18. 算术收益率与对数收益率(几何收益率)
  19. IP地址和 MAC地址详解
  20. 春节攻防战的战前谋划-电商必看

热门文章

  1. html网页代码入门,html 网页入门(示例代码)
  2. web和python哪个好_用python开发app和web哪个比较容易?
  3. rust哪里油桶多_我们在说Filecoin的时候为什么要说rust语言
  4. 安卓如何让listview在上下两个按钮之间充满_如何提高超声波塑胶焊接机生产效率...
  5. html的经典语法大全,HTML语法大全
  6. java适配器模式 场景_详解Java适配器模式
  7. uiactionsheet 代理_iOS UIActionSheet (点击事件笔记)
  8. Python项目开发基础 -- with open (filename) as 读写文件
  9. redis cluster 分布式锁_Redis的分布式锁的实现原理
  10. 使用Gensim进行主题建模(二)