2019独角兽企业重金招聘Python工程师标准>>>

阅读目录

一、尽量不要锁住方法

二、缩小同步代码块,只锁数据

三、锁中尽量不要再包含锁

四、将锁私有化,在内部管理锁

五、进行适当的锁分解

正文

并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问。加锁会带来性能上的损坏,似乎是众所周知的事情。然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程。【Redis实现的分布式锁和分布式限流】

如果只有一个线程竞争锁,此时并不存在多线程竞争的情况,那么JVM会进行优化,那么这时加锁带来的性能消耗基本可以忽略。因此,规范加锁的操作,优化锁的使用方法,避免不必要的线程竞争,不仅可以提高程序性能,也能避免不规范加锁可能造成线程死锁问题,提高程序健壮性。下面阐述几种锁优化的思路。

一、尽量不要锁住方法

在普通成员函数上加锁时,线程获得的是该方法所在对象的对象锁。此时整个对象都会被锁住。这也意味着,如果这个对象提供的多个同步方法是针对不同业务的,那么由于整个对象被锁住,一个业务业务在处理时,其他不相关的业务线程也必须wait。下面的例子展示了这种情况:

运行程序,可以看到在线程bussa 执行的过程中,bussb是不能够进入函数 busiB()的,因为此时lockMethod 的对象锁被线程bussa获取了。【Git内部原理之Git对象】

二、缩小同步代码块,只锁数据

有时候为了编程方便,有些人会synchnoized很大的一块代码,如果这个代码块中的某些操作与共享资源并不相关,那么应当把它们放到同步块外部,避免长时间的持有锁,造成其他线程一直处于等待状态。尤其是一些循环操作、同步I/O操作。

不止是在代码的行数范围上缩小同步块,在执行逻辑上,也应该缩小同步块,例如多加一些条件判断,符合条件的再进行同步,而不是同步之后再进行条件判断,尽量减少不必要的进入同步块的逻辑。

三、锁中尽量不要再包含锁

这种情况经常发生,线程在得到了A锁之后,在同步方法块中调用了另外对象的同步方法,获得了第二个锁,这样可能导致一个调用堆栈中有多把锁的请求,多线程情况下可能会出现很复杂、难以分析的异常情况,导致死锁的发生。下面的代码显示了这种情况:【Java 编程中关于异常处理的 10 个最佳实践】

四、将锁私有化,在内部管理锁

把锁作为一个私有的对象,外部不能拿到这个对象,更安全一些。对象可能被其他线程直接进行加锁操作,此时线程便持有了该对象的对象锁,例如下面这种情况:

这种使用方式下,对象a的对象锁被外部所持有,让这把锁在外部多个地方被使用是比较危险的,对代码的逻辑流程阅读也造成困扰。一种更好的方式是在类的内部自己管理锁,外部需要同步方案时,也是通过接口方式来提供同步操作:

五、进行适当的锁分解

考虑下面这段程序:

在这个例子中,join方法只使用一个同步锁,来获取tables中的List对象,然后判断玩家数量是不是小于9,如果是,就调增加一个玩家。当有成千上万个List存在tables中时,对tables锁的竞争将非常激烈。面【试中常问的List去重问题,你都答对了吗?】

在这里,我们可以考虑进行锁的分解:快速取出数据之后,对List对象进行加锁,让其他线程可快速竞争获得tables对象锁:

扩展阅读

七点建议助您写出优雅的Java代码

实战经验分析,如何优雅地处理 Java 异常

SpringBoot (六) :如何优雅的使用 mybatis

程序员面试过程中,该怎么判断该公司好坏

如何在面试中介绍自己的项目经验

【面试现场】如何在10亿数中找出前1000大的数

来源:https://www.cnblogs.com/QG-whz/p/8351298.html

转载于:https://my.oschina.net/javafirst/blog/3043799

Java多线程编程 — 锁优化相关推荐

  1. java多线程编程——锁优化

    并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...

  2. java单线程上锁_关于Java多线程编程锁优化的深入学习

    正文 并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过 ...

  3. Java多线程编程—锁优化

    并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...

  4. java多线程编程01---------基本概念

    一. java多线程编程基本概念--------基本概念 java多线程可以说是java基础中相对较难的部分,尤其是对于小白,次一系列文章的将会对多线程编程及其原理进行介绍,希望对正在多线程中碰壁的小 ...

  5. Java多线程编程那些事:volatile解惑--转

    http://www.infoq.com/cn/articles/java-multi-thread-volatile/ 1. 前言 volatile关键字可能是Java开发人员"熟悉而又陌 ...

  6. Java多线程编程:交替打印数字1234和字母abcd

    Java多线程编程:交替打印数字1234和字母abcd 1. 使用synchronized同步锁 2. 使用LockSupport类 2.1 LockSupport介绍 3. 使用AtomicInte ...

  7. Java多线程开发(一)Java多线程编程简介

    文章目录 参考 Java线程简介 Thread类构造方法和属性 常用Thread类方法 线程的生命周期 多线程编程的优势和风险 安全性问题 活跃性问题 性能问题 参考 [Java并发系列01]Thre ...

  8. Java 多线程编程核心技术

    课程介绍 多线程编程在最大限度利用计算资源.提高软件服务质量方面扮演着至关重要的角色,而掌握多线程编程也成为了广大开发人员所必须要具备的技能. 本课程以基本概念.原理方法为主线,每篇文章结合大量演示实 ...

  9. Java多线程编程模式实战指南(二):Immutable Object模式--转载

    本文由本人首次发布在infoq中文站上:http://www.infoq.com/cn/articles/java-multithreaded-programming-mode-immutable-o ...

最新文章

  1. python selenium --调用js
  2. 如何优雅的解决mac安装zsh不执行.bash_profile
  3. 135. Leetcode 46. 全排列 (回溯算法-排列问题)
  4. 只读字符串的c语言命令,C语言只读空间 - C 语言程序设计
  5. idea for循环快捷键_IDEA骚技巧,编码速度至少快一倍
  6. 小白来学C语言之宏定义(#define)
  7. oracle服务名连接慢,数据库 – Oracle SID和服务名称;连接问题
  8. 关于windows的进程处理(三)
  9. Java对MySql数据库进行备份与还原
  10. Codeforces 165D Beard Graph 边权树剖+树状数组
  11. 命令查询职责分离模式 CQRS Command Query Responsibility Segregation
  12. U3D AND UDK 各自特点
  13. 《R语言初学者指南》pdf
  14. 深圳大学计算机保护一志愿吗,考研保护第一志愿是什么意思?哪些院校官宣保护一志愿?...
  15. 笔记本电脑桌面计算机图标不见了怎么办,桌面图标不见了怎么办,教您电脑桌面图标不见了怎么办...
  16. VS2010序列号正式版附破解方法详细攻略
  17. QQ小游戏 微信小游戏 即时通信 IM 删除会话 deleteConversation sdk
  18. hdu6287 口算训练(质因子分解,二分)
  19. 新西兰梅西大学计算机专业研究生,新西兰梅西大学硕士读几年,新西兰专升硕 | 能进八大,还有机会移民,最快1.5年完成!...
  20. 【响应式Web前端设计】i标签和em标签的区别

热门文章

  1. ds证据理论python实现_ALI模型理论以及Python实现
  2. mysql分区列要包含主键吗_MYSQL的分区字段,必须包含在主键字段内
  3. java 反编译 类名_java javassist创建类和反编译类
  4. IBM连续两年大数据市场占有率全球第一
  5. 阻塞队列BlockingQueue用法
  6. UITableView 界面小实例
  7. JMS : Java Message Service (Java消息服务)之一 [转]
  8. linux下tar解压特定的目录
  9. GridView导出为Excel
  10. BZOJ4012 [HNOI2015]开店