本文转载自java中synchronized与Lock的异同

前言

synchronized和Lock通过互斥保障原子性,能够保护共享数据以实现线程安全,其作用包括保障原子性、可见性、有序性

常见问题

在平时聊天或者面试过程中,可能会被问到,既然已经有了synchronized了,为什么JSR166小组花这么多时间来开发j.u.c的Lock框架呢,换句话说就是内部锁和显示锁之前有什么区别?

分析

synchronized(内部锁)

java平台中的任何一个对象都有唯一一个与之关联的锁,这种锁称为监视器(Monitor)或者内部锁(Intrinsic Lock),内部锁是通过synchronized关键字实现的,可以用来修饰方法(同步方法、静态方法)、代码块(临界区)

Lock(显示锁)

JDK1.5开始引入的排他锁,默认实现是ReetrantLock,作为一种线程同步机制,其拥有和synchronized相同的语义,并且还提供了一些synchronized不具备的特性

差异

从本质上来讲

synchronized是在JVM层面实现的,

ReetrantLock是java API层面实现的排它锁,系统无法自动释放锁,需要在代码中的finally子句中显示释放,否则会出现锁泄漏

从安全上来讲

内部锁在退出临界出时,会自动释放锁,不会导致锁泄漏

外部锁如果未主动释放锁或者释放代码在finally子句中,容易导致锁泄漏

从使用上来讲

synchronized可以修饰方法,修饰代码块,但是内部锁的申请与释放只能在一个方法内进行,因为代码无法跨方法

Lock,只能修饰代码块,但是它可以发挥面向对象编程的灵活性,显示锁的申请在一个方法,在另一个方法里释放锁

在锁的调度方面

内部锁公平锁,显示锁即支持非公平也支持公平锁

在问题定位方面

线程转储可能无法包含显示锁的相关信息,从而导致问题定位困难。比如果在JDK1.5下线程转储中会包含内部锁的相关信息,不包含显示锁的信息

从性能方面方面

等待同一把内部锁的线程,都在同一个等待队列中,等待系统调度,而ReentrantLock锁,可以通过Condition条件变量,实现分组等待的效果,所以性能表现上更好一些

从其它特性方面

当一个线程在等待获取一个锁时,因为线程活性故障导致其永远无法获取得锁时,使用内部锁的线程会一直傻傻的等待一个无法获得的锁,换句话说,内部锁缺少可中断的特性,

显示锁它拥有与内部锁相同的并发性和内存主义,但是添加了轮询锁定时锁等候可中断锁等候一些新特性,使其在激烈争用情况下表现出更好的性能,因为当多线程访问共享资源时,JVM可以将更多的时间用于执行线程上,而不是浪费时间在线程调度上。

  • 轮询锁意味着,ReentrantLock支持公平锁,可以通过轮询的方式依次获取锁
  • 定时锁等候意味着,线程在N长时间之内无法获取到锁,就会返回false ,表示获取锁失败,tryLock方法,不会像内部锁一样痴痴的等待一个没有结果的未来
  • 可中断锁等待,意味着ReentrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly()来实现这个机制。

如何选择

如果你使用的是JDK1.5的话,在争用不高的时候可以使用内部锁,在争用高的情况下,建议使用显示锁

如果你使用的是JDK1.5+的版本,随着对内部锁的优化(锁消除、锁粗化、偏向锁、自适应锁),两都之间的性能差异已经缩小了很多,如果后期内部锁的这些优化可以应用到显示锁的话,那性能可能就会有很大差距了。

总体上来说,在资源竞争不激烈的情形下,性能稍微比synchronized差点点。但是资源竞争非常激烈的时候,synchronized的性能会下降很多,而ReentrantLock的性能表现仍然比较稳定。

结束语

在工作中,为了保证线程安全我们不一定要使用锁,可以使用一些轻量级的同步工具或者无锁的框架和工具,来提升应用的性能。

java中synchronized与Lock的异同的更多相关文章

  1. JAVA中synchronized和lock详解

         目前在Java中存在两种锁机制:synchronized和Lock,Lock接口及其实现类是JDK5增加的内容,其作者是大名鼎鼎的并发专家Doug Lea.本文并不比较synchronize ...

  2. Java中Synchronized和Lock的使用

    Lock的锁定是通过代码实现的,而 synchronized 是在 JVM 层面上实现的 synchronized在锁定时如果方法块抛出异常,JVM 会自动将锁释放掉,不会因为出了异常没有释放锁造成线 ...

  3. Java中synchronized和Lock的区别

    synchronized和Lock的区别synchronize锁对象可以是任意对象,由于监视器方法必须要拥有锁对象那么任意对象都可以调用的方法所以将其抽取到Object类中去定义监视器方法这样锁对象和 ...

  4. Java并发指南4:Java中的锁 Lock和synchronized

    Java中的锁机制及Lock类 锁的释放-获取建立的happens before 关系 锁是java并发编程中最重要的同步机制.锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消 ...

  5. java中synchronized的用法详解

    记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchron ...

  6. java中synchronized的使用方法与具体解释

    Java语言的keyword.当它用来修饰一个方法或者一个代码块的时候,可以保证在同一时刻最多仅仅有一个线程运行该段代码. 一.当两个并发线程訪问同一个对象object中的这个synchronized ...

  7. Java 中 synchronized的用法详解(四种用法)

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码.本文给大家介绍java中 synchronized的用法,对本文感兴趣的朋友一起看看吧 ...

  8. java中 synchronized 的使用,确保异步执行某一段代码。

    最近看了个有关访问网络url和下载的例子,里面有几个synchronized的地方,系统学习下,以下内容很重要,记下来. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一 ...

  9. JAVA 中 synchronized 详解

    看到一篇关于JAVA中synchronized的用法的详解,觉得不错遂转载之..... 原文地址: http://www.cnblogs.com/GnagWang/archive/2011/02/27 ...

随机推荐

  1. jQuery基础介绍

    最近在学习JavaScript,当学习Javascript之后,不得不学习的肯定是jQuery了,所以开始利用网络的便捷浏览各大博客寻找可学习的资源.这篇博客关于jQuery的学习让我有很多收获,也明 ...

  2. docker镜像加速,docker更换为国内镜像

    docker镜像加速,docker更换为国内镜像 一.使用官方镜像 二.Docker守护进程配置加速器 相关博文原文地址: CSDN:让我思考一下 :docker更换为国内镜像 一.使用官方镜像 Do ...

  3. Centos 搭建Hadoop

    Centos搭建Hadoop 一.搭建Hadoop需要JDK环境,首先配置JDK 二.下载haoop 三.在Centos服务器上解压下载好的安装包 四.修改配置文件 4.1 hadoop-env.sh ...

  4. C++类基本--随笔一

    #include <iostream> using namespace std; class Teacher { public: Teacher(int m=3,int n=2) { a= ...

  5. KVM (虚拟机创建及管理,存储管理)

    创建KVM虚拟机 1.图形化界面创建 第一步:查看软件包组 yum grouplist 第二步:下载GUI界面的软件包组 yum groupinstall "Server with GUI& ...

  6. python3 自动部署MariaDB主从复制

    master import configparser import os def config_mariadb_yum(): exists = os.path.exists('/etc/yum.rep ...

  7. Web APP和原生 APP的不同

    我们现在手机中的APP,大部分都是混合APP,也就是既用到了原生APP的基础,又用到了Web APP的基础,混合的比例从0%到100%之间不等.更好的了解APP的类型,有助于我们学则合适的测试策略.今 ...

  8. 设计模式(十七)——迭代器模式(ArrayList 集合应用源码分析)

    1 看一个具体的需求 编写程序展示一个学校院系结构:需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院, 一个学院有多个系.如图: 2 传统的设计方案(类图) 3 传统的方式的问题分析 ...

  9. [POJ1985] Cow Marathon 「树的直径」

    >传送门< 题意:求树的直径 思路:就是道模板题,两遍dfs就求出来了 Code #include <cstdio> #include <iostream> #in ...

  10. 一、Jmeter进行Mysql数据库的压测

    1.首先需要安装配置mysql数据库连接驱动:mysql-connector-java-5.1.28.jar 1.1 网上很多资源,可自行下载: 1.2 下载完成后,分别将该jra包,存放到:jmet ...