这一章节我们接着上一章节的问题,给出一个解决方式:对象锁。

1.什么是对象锁?

对象锁是指Java为临界区synchronized(Object)语句指定的对象进行加锁,对象锁是独占排他锁。

2.什么是临界区?

临界区是指程序中的一个代码段,在这段代码中,单独并发的线程对同一个对象进行訪问。在Java中。用keyword“synchronized”标识一个临界区。

3.经常使用的对象锁:synchronized和ReentrantLock

我们以下给出两个代码样例(以下两个样例都是依据之前的银行的代码来改动的。主要改动Bank的代码,其它的不变):

代码帖子连接:http://blog.csdn.net/raylee2007/article/details/50496784

改动的代码:

使用synchronized

  1. package com.ray.ch17;
  2.  
  3. public class Bank {
  4. private final double[] accounts;
  5.  
  6. public double[] getAccounts() {
  7. return accounts;
  8. }
  9.  
  10. public Bank(int n, double initBalance) {
  11. accounts = new double[n];
  12. for (int i = 0; i < accounts.length; i++) {
  13. accounts[i] = initBalance;
  14. }
  15. }
  16.  
  17. public double getTotal() {
  18. double total = 0;
  19. for (int i = 0; i < accounts.length; i++) {
  20. total += accounts[i];
  21. }
  22. return total;
  23. }
  24.  
  25. public synchronized void transfer(int fromAccount, int toAccount,
  26. double money) {
  27. if (accounts[fromAccount] < money) {
  28. return;
  29. }
  30. accounts[fromAccount] -= money;
  31. System.out.printf("从" + fromAccount + "账户转出%10.2f元,", money);
  32. accounts[toAccount] += money;
  33. System.out.printf("从" + toAccount + "账户转入%10.2f元,", money);
  34. System.out.printf("总数:%10.2f元", getTotal());
  35. System.out.println();
  36. }
  37.  
  38. public int size() {
  39. return accounts.length;
  40. }
  41. }

使用ReentrantLock:

  1. package com.ray.ch17;
  2.  
  3. import java.util.concurrent.locks.ReentrantLock;
  4.  
  5. public class Bank {
  6. private final double[] accounts;
  7.  
  8. private ReentrantLock reentrantLock = new ReentrantLock();
  9.  
  10. public double[] getAccounts() {
  11. return accounts;
  12. }
  13.  
  14. public Bank(int n, double initBalance) {
  15. accounts = new double[n];
  16. for (int i = 0; i < accounts.length; i++) {
  17. accounts[i] = initBalance;
  18. }
  19. }
  20.  
  21. public double getTotal() {
  22. double total = 0;
  23. for (int i = 0; i < accounts.length; i++) {
  24. total += accounts[i];
  25. }
  26. return total;
  27. }
  28.  
  29. public void transfer(int fromAccount, int toAccount, double money) {
  30. reentrantLock.lock();
  31. try {
  32. if (accounts[fromAccount] < money) {
  33. return;
  34. }
  35. accounts[fromAccount] -= money;
  36. System.out.printf("从" + fromAccount + "账户转出%10.2f元,", money);
  37. accounts[toAccount] += money;
  38. System.out.printf("从" + toAccount + "账户转入%10.2f元,", money);
  39. System.out.printf("总数:%10.2f元", getTotal());
  40. System.out.println();
  41. } finally {
  42. reentrantLock.unlock();
  43. }
  44. }
  45.  
  46. public int size() {
  47. return accounts.length;
  48. }
  49. }

通过測试代码输出:

从16账户转出   6853.31元,从80账户转入   6853.31元,总数:1000000.00元
从5账户转出    819.37元,从92账户转入    819.37元,总数:1000000.00元
从12账户转出   1278.62元,从67账户转入   1278.62元,总数:1000000.00元
从3账户转出   1353.74元,从9账户转入   1353.74元,总数:1000000.00元
从94账户转出   2316.07元,从83账户转入   2316.07元,总数:1000000.00元
从59账户转出   2563.51元,从90账户转入   2563.51元,总数:1000000.00元
从82账户转出   6276.89元,从30账户转入   6276.89元,总数:1000000.00元
从2账户转出   6175.01元,从80账户转入   6175.01元,总数:1000000.00元
从21账户转出   5030.61元,从80账户转入   5030.61元,总数:1000000.00元

......(等等)

通过输出能够看见。总数已经是不再变动,不再出现误差。

总结:这一章节主要讨论了同步的方法:对象锁,以及经常使用的两个对象锁。

这一章节就到这里。谢谢。

-----------------------------------

文件夹

从头认识java-17.4 具体解释同步(3)-对象锁的更多相关文章

  1. java线程同步以及对象锁和类锁解析(多线程synchronized关键字)

    一.关于线程安全 1.是什么决定的线程安全问题? 线程安全问题基本是由全局变量及静态变量引起的. 若每个线程中对全局变量.静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的:若有多个线 ...

  2. java的synchronized有没有同步的类锁?

    转自:http://langgufu.iteye.com/blog/2152608 http://www.cnblogs.com/beiyetengqing/p/6213437.html 没有... ...

  3. 简单测试Java线程安全中阻塞同步与非阻塞同步性能

    摘抄自周志明老师的<深入理解Java虚拟机:JVM高级特性与最佳实践>13.2.2 线程安全的实现方法 1.名词解释 同步是指锁哥线程并发访问共享数据时,保证共享数据同一时刻只被一个线程访 ...

  4. Java:多线程,线程同步,synchronized关键字的用法(同步代码块、非静态同步方法、静态同步方法)

    关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨synchronized关键字. sy ...

  5. JAVA多线程之Synchronized关键字--对象锁的特点

    一,介绍 本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点. 所谓对象锁,就是就是synchronized 给某个对象 加锁.关于 对象锁 可参考:这篇文章 二,分析 s ...

  6. [Java开发之路](9)对象序列化与反序列化

    1. 对象序列化 当你创建对象时.仅仅要你须要.它会一直存在,可是程序终止时,不管何时它都不会继续存在.虽然这样做是很有意义的,可是在某些情况下.假设程序不执行时扔能存在而且保存其信息,那将对我们很实 ...

  7. java 线程​基本概念 可见性 同步

    开发高性能并发应用不是一件容易的事情.这类应用的例子包括高性能Web服务器.游戏服务器和搜索引擎爬虫等.这样的应用可能需要同时处理成千上万个请求.对于这样的应用,一般采用多线程或事件驱动的架构.对于J ...

  8. “全栈2019”Java第九章:解释第一个程序

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  9. Java并发编程(您不知道的线程池操作), 最受欢迎的 8 位 Java 大师,Java并发包中的同步队列SynchronousQueue实现原理

    Java_并发编程培训 java并发程序设计教程 JUC Exchanger 一.概述 Exchanger 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchan ...

随机推荐

  1. 如何建立远程桌面连接(XP、Vista、Win7)

    如何建立远程桌面连接(XP.Vista.Win7) 要求: 1:对方即你要连的机器必须要允许远程桌面连接,操作系统一般是winXP(单用户)和win2003server(多用户),具体设置:右击我的电 ...

  2. React开发实时聊天招聘工具 -第二章

    2-1 介绍React开发环境 npm install -g create-react-app xxx npm run eject   来配置webpack 2-2 ES6常用语法 其他 还有一些特性 ...

  3. 03015_DBUtils

    1.概述 (1)如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils : (2)DBUtils就是JDBC ...

  4. ASP.NET中的几种弹出框提示

    B/S不像C/S那样一个MessageBox就可以弹出提示框,不过可以通过js的“Alert”来弹出消息,或者通过一些变种的js方法.下面我给大家介绍几种,希望大家喜欢. 四种弹出框代码: prote ...

  5. amaze ui响应式辅助

    amaze ui响应式辅助 响应式辅助 就是不同的显示屏幕,或者手机的横竖屏,你可以控制栏目的显影,还是挺有帮助的 视口大小 .am-[show|hide]-[sm|md|lg][-up|-down| ...

  6. Cloudera Hue是什么?

     Hue是cdh专门的一套web管理器,它包括3个部分hue ui,hue server,hue db.hue提供所有的cdh组件的shell界面的接口.你可以在hue编写mr,查看修改hdfs的文件 ...

  7. 洛谷P1908 逆序对(归并排序)

    题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定 ...

  8. springboot扫描通用的依赖模块

    将实际使用类的启动类改为如下形式启动: public class OrderApplication { public static void main(String[] args) { Object[ ...

  9. spark源码编译,本地调试

    1.下载源码 2.进入源码根据README.md编译源码,注意使用的是源码目录下的maven编译 3.用idea导入顶层pom文件 4.修改顶层pom文件和example下的pom文件,将scope的 ...

  10. 如何在canvas中画出一个太极图

    先放一个效果图: 代码如下 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /&g ...