1.synchronized
加同步格式:

synchronized(需要一个任意的对象(锁)){

代码块中放操作共享数据的代码。

}

synchromized缺陷
synchronized是java中的一个关键字,也就是说是java语言的内置的特性。

如果一个代码块被synchronized修饰,当一个线程获取了对应的锁,并执行代码块时,其他线程只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:

(1)获取锁的线程执行完了改代码块,然后线程释放对锁的占有

(2)线程执行发生异常,此时JVM会让线程自动释放锁。

例子1:

  如果这个获取锁的线程由于要等待IO或者其他原因(比如调用sleep方法)被阻塞了,但是又没有释放锁,其他线程便只能干巴巴地等待,试想一下,这多么影响程序执行效率。

  因此就需要有一种机制可以不让等待的线程一直无期限地等待下去(比如只等待一定的时间或者能够响应中断),通过Lock就可以办到。

例子2:

当有多个线程读写文件时,读操作和写操作会发生冲突现象,写操作和写操作会发生冲突现象,但是读操作和读操作不会发生冲突现象。

  但是采用synchronized关键字来实现同步的话,就会导致一个问题:

如果多个线程都只是进行读操作,当一个线程在进行读操作时,其他线程只能等待无法进行读操作。

  因此就需要一种机制来使得多个线程都只是进行读操作时,线程之间不会发生冲突,通过Lock就可以办到。

  另外,通过Lock可以知道线程有没有成功获取到锁。这个是synchronized无法办到的。

  总的来说,也就是说Lock提供了比synchronized更多的功能。

2.lock
lock和synchronized的区别
(1)lock不是java语言内置的,synchronized是java语言的关键字,因此是内置特性。lock是一个类,通过这个类可以实现同步访问;

(2)lock和synchronized有一点非常大的不同,采用synchronized不需要用户手动的去释放锁,当synchronized方法或者代码块执行完毕之后,系统会自动的让线程释放对锁的占有,而lock则必须要用户去手动释放锁,如果没有主动的释放锁,就会可能导致出现死锁的现象

LOCK
首先要说明的就是,通过查看LOCK 的源码可知道,lock是一个接口

lock接口中每个方法的使用:lock()、tryLock()、tryLock(long time, TimeUnit unit)、lockInterruptibly()是用来获取锁的。 unLock()方法是用来释放锁的。

四个获取锁方法的区别:
(1)lock()方法时平常使用的最多的一个方法,就是用来获取锁的,如果锁已经被其他线程获取,则进行等待。

由于在前面讲到如果采用lock,必须主动去释放锁,并且在发生异常时,不会自动释放锁。因此一般来说,使用lock必须在try{}catch{}块中进行,并且将释放锁的操作放在finally块中进行,以保证锁一定被释放掉,房主死锁的发生。

(2)tryLock()方法是有返回值的,他表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已经被其他线程获取),则返回false,也就说这个方法无论如何都会立即返回。在拿不到锁时不会一直在哪里等待

(3)tryLock(long time, TimeUnit unit)方法和tryLock()方法时类似的,只不过区别在于这个方法在拿不到锁时会等待一定时间,在时间限制之内如果还是拿不到锁,就返回false。如果一开始就拿到锁或者在等待期间内拿到了锁,则就返回true。

(4)lockinterruptibly()方法比较特殊,当通过这个方法区获取锁时,如果线程正在等待获取锁,则这个线程能够相应中断,即中断线程的等待状态。也就是说,当连个线程同时通过lock.lockinterruputibly()向获取某个锁时,假如此时线程A获取到了锁,而线程B只有等待,那么对线程调用threadB.interrupt()方法能够中断线程B的等待过程。

注意:当一个线程获取了锁之后,是不会被interrupt()方法中断的

因此当通过lockinterruptibly()方法获取某个锁时,如果不能获取到,只有进行等待的情况下,是可以相应中断的

而用synchronized修饰的话,当一个线程处于等待某个锁的状态,是无法被中断的,只有一直等待下去。

ReentrantLock

直接使用lock接口的话,我们需要实现很多方法,不太方便,ReentrantLock是唯一实现了Lock接口的类,并且ReentrantLock提供了更多的方法,ReentrantLock,意思是“可重入锁”。

ReadWriteLock也是一个接口,在它里面只定义了两个方法:

一个用来获取读锁,一个用来获取写锁。也就是说将文件的读写操作分开,分成2个锁来分配给线程,从而使得多个线程可以同时进行读操作。ReentrantReadWriteLock实现了ReadWriteLock接口。

ReentrantReadWriteLock

ReentrantReadWriteLock里面提供了很多丰富的方法,不过最主要的两个方法:readlock()和writelock用来获取读锁和写锁

注意:

  不过要注意的是,如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。

如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。

3.LOCK和SYNCHRONIZED的选择
(1)lock是一个接口,而synchronized是java的关键字,synchronized是内置的语言实现;

(2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而lock在发生异常时,如果没有主动通过unlock()去释放锁,则很可能造成死锁现象,因此使用lock()时需要在finally块中释放锁;

(3)lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不讷讷狗狗响应中断

(4)通过lock可以知道有没有成功获取锁,而synchronized却无法办到

(5)lock可以挺高多个线程进行读操作的效率

在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而竞争资源非常激烈是(既有大量线程同时竞争),此时lock的性能要远远优于synchronized。所以说,在具体使用时适当情况选择。

synchronized和lock的使用分析(优缺点对比详解)的更多相关文章

  1. vue和react全面对比(详解)

    vue和react对比(详解) 放两张图镇压小妖怪 本文先讲共同之处, 再分析区别 大纲在此: 共同点: a.都使用虚拟dom b.提供了响应式和组件化的视图组件 c.注意力集中保持在核心库,而将其他 ...

  2. Android Telephony分析(五) ---- TelephonyRegistry详解

    本文紧接着上一篇文章<Android Telephony分析(四) —- TelephonyManager详解 >的1.4小节.从TelephonyRegistry的大部分方法中: 可以看 ...

  3. Android Telephony分析(三) ---- RILJ详解

    前言 本文主要讲解RILJ工作原理,以便更好地分析代码,分析业务的流程.这里说的RILJ指的是RIL.java (frameworks\opt\telephony\src\java\com\andro ...

  4. Android Telephony分析(二) ---- RegistrantList详解

    前言 本文主要讲解RegistrantList的原理,以及如何快速分析RegistrantList相关的代码流程.在Telephony模块中,在RIL.Tracker(ServiceStateTrac ...

  5. Windows8 各种版本区别对比详解

    微软的 Windows8 操作系统提供了4个不同的版本,分别是 Windows RT.Windows 8 标准版.Windows 8 Pro 专业版 以及 Windows 8 Enterprise 企 ...

  6. 【集合框架】JDK1.8源码分析之ArrayList详解(一)

    [集合框架]JDK1.8源码分析之ArrayList详解(一) 一. 从ArrayList字表面推测 ArrayList类的命名是由Array和List单词组合而成,Array的中文意思是数组,Lis ...

  7. “全栈2019”Java第四十九章:重载与重写对比详解

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

  8. nginx源码分析线程池详解

    nginx源码分析线程池详解 一.前言     nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影响.但是经常会有人问道,n ...

  9. explain分析SQL语句详解

    性能分析explain MySql Query Optimizer是MySql中专门负责优化select语句的优化器模块,主要功能:通过计算分析系统中收集到的系统信息,为客户端请求的Query提供他认 ...

随机推荐

  1. FineReport打印方式(转)

    1. 报表打印机制 各种打印的运行机制,都是选择打印时,先根据报表内容,在服务器的内存中将页面中的内容全部生成完毕,即生成对应格式的对象:然后再由serverlet直接推送给客户端,最后根据选择的打印 ...

  2. Lombok 注解简介

    Lombok @AllArgsConstructor /** * 生成一个包含所有属性的构造函数 */ @Target(ElementType.TYPE) @Retention(RetentionPo ...

  3. Flink整体执行流程

    以Flink源码中自带的WordCount为例,执行的入口从用户程序的execute()函数入手,execute()的源码如下: public JobExecutionResult execute(S ...

  4. Flink集群环境搭建

    环境准备 master:171:slave:171,172:flink版本:1.3.0 下载地址:http://archive.apache.org/dist/flink/flink-1.3.0/ 集 ...

  5. web端测试的测试点和注意事项

    工作中接触了不同类型的web端系统,内容不同,需求不同,测试关注点也存在些许的不同,但是总体测试思路和关注的点都类似,下面是总结自己所接触的web端系统测试的一些测试点,不尽全面,以后接触新的业务系统 ...

  6. JMeter常用的4种参数化方式-操作解析

    目录结构 一.JMeter参数化简介 1.JMeter参数化的概念 2.JMeter参数化方式之使用场景对比 二.JMeter参数化的4种主要方式-操作演练 1.User Parameters(用户参 ...

  7. Python --链接MYSQL数据库与简单操作 含SSH链接

    项目是软硬件结合,在缺少设备的情况,需要通过接口来模拟实现与设备的交互,其中就需要通过从数据库读取商品的ID信息 出于安全考虑  现在很多数据库都不允许通过直接访问,大多数是通过SSH SSH : 数 ...

  8. seaborn用heatmap画热度图

    原文链接 https://blog.csdn.net/m0_38103546/article/details/79935671

  9. 应用安全 - 工具 | 平台 - Weblogic - 漏洞 - 汇总

    控制台路径 | 弱口令  前置条件 /console CVE-2016-0638  Date 类型远程代码执行 影响范围10.3.6, 12.1.2, 12.1.3, 12.2.1  CVE-2016 ...

  10. (转载)深入解析String#intern

    本文转载自:深入解析String#intern 引言 在 JAVA 语言中有8中基本类型和一种比较特殊的类型String.这些类型为了使他们在运行过程中速度更快,更节省内存,都提供了一种常量池的概念. ...