Java高级特性—锁

1).synchronized
  加同步格式:
    synchronized( 需要一个任意的对象(锁) ){
      代码块中放操作共享数据的代码。
    }
  synchronized的缺陷
   synchronized是java中的一个关键字,也就是说是Java语言内置的特性。
     如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,
     等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:
    1)获取锁的线程执行完了该代码块,然后线程释放对锁的占有;
    2)线程执行发生异常,此时JVM会让线程自动释放锁。

2).Lock
  lock和synchronized的区别
   1).Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这个类可以实现同步访问;
   2).Lock和synchronized有一点非常大的不同,采用synchronized不需要用户去手动释放锁,
    当synchronized方法或者synchronized代码块执行完之后,系统会自动让线程释放对锁的占用;
    而Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。
  3).java.util.concurrent.locks包下常用的类,lock是一个接口
  4).Lock接口中每个方法的使用:
    lock()、tryLock()、tryLock(long time, TimeUnit unit)、lockInterruptibly()是用来获取锁的。
    unLock()方法是用来释放锁的
  5).四个获取锁方法的区别:
    lock()方法是平常使用得最多的一个方法,就是用来获取锁。如果锁已被其他线程获取,则进行等待。

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

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

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

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

   注意,当一个线程获取了锁之后,是不会被interrupt()方法中断的。
   因此当通过lockInterruptibly()方法获取某个锁时,如果不能获取到,只有进行等待的情况下,是可以响应中断的。
   而用synchronized修饰的话,当一个线程处于等待某个锁的状态,是无法被中断的,只有一直等待下去。

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

  一个用来获取读锁,一个用来获取写锁。也就是说将文件的读写操作分开,分成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。所以说,在具体使用时要根据适当情况选择

原文地址:https://www.cnblogs.com/atomicbomb/p/9904242.html

时间: 2024-10-11 13:48:03

Java高级特性—锁的相关文章

Java高级特性 第6节 注解(初步认识)

转自https://www.cnblogs.com/xdp-gacl/p/3622275.html的博客 一.认识注解 注解(Annotation)很重要,未来的开发模式都是基于注解的,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解的,现在的Struts2有一部分也是基于注解的了,注解是一种趋势,现在已经有不少的人开始用注解了,注解是JDK1.5之后才有的新特性 JDK1.5之后内部提供的三个注解 @Deprecated 意思是“废弃的,过时的

Java 高级特性: Lambda 表达式

本文源代码上传到了码云,请点击 LambdaExpression 获取.Lambda 表达式是 java 8 的新特性,本文讲解了 lambda 表达式的所有知识.内容涉及到 lambda 表达式是什么, lambda 表达式用在何处,在 GUI 应用程序中使用 lambda 表达式,lambda 表达式语法,变量访问权限,目标类型,序列化,方法引用等.

java高级特性--注解,这也许是最简单易懂的文章了

博主在初学注解的时候看到网上的介绍大部分都是直接介绍用法或者功能,没有实际的应用场景,篇幅又很长导致学习的时候难以理解其意图,而且学完就忘QAQ.本篇文章中我将结合实际的应用场景尽可能由浅入深,平缓的介绍java注解. java注解是jdk1.5以后新出的特性,对于它的应用非常广泛,我们首先来看一下注解的应用,百度百科上这样说: 我们可以看到,注解的作用有三方面: 编写doc文档:这个就我们很常用的 @return 以及 @author,加了这些注解以后,就可以用jdk帮我们自动生成对应的API

Java高级特性——注解,这也许是最简单易懂的文章了

java注解是jdk1.5以后新出的特性,对于它的应用非常广泛,我们首先来看一下注解的应用,百度百科上这样说: 我们可以看到,注解的作用有三方面: 编写doc文档:这个就我们很常用的 @return 以及 @author,加了这些注解以后,就可以用jdk帮我们自动生成对应的API文档了 编译检查:这个也很常见 @Override,而且功能很强大,我将会在以后的文章中介绍 进行代码分析:这是本篇文章的重点.这个和编译检查一样也是一个强大的功能,但相比与编译检查由于其用到了反射,在性能上存在一些问题

Java高级特性—JVM

1).java监控工具使用 jconsole是一种集成了上面所有命令功能的可视化工具,可以分析jvm的内存使用情况和线程等信息 visualvm 提供了和jconsole的功能类似,提供了一大堆的插件. 插件中,Visual GC(可视化GC)还是比较好用的,可视化GC可以看到内存的具体使用情况. 2).Java虚拟机运行时数据区域划分 被分为五个区域:堆(Heap).栈(Stack).本地方法栈(Native Stack). 方法区(Method Area).程序计数器(Program Cou

Java高级特性 第1节 集合框架和泛型

Java中,存储多个同类型的数据,可以用数组来实现,但数组有一些缺陷: 数组长度固定不变,布恩那个很好的适应元素数量动态变化的情况 可以通过数组.length获取数组长度,却无法直接获取数组中实际存储的元素个数 数组采用在内存中分配连续空间的方式存储,根据元素信息查找时的效率比较低,需要多次比较 Java提供了一套性能优良.使用方便的接口和类,他们都位于java.util包中. 一.Java中的集合 Java集合类主要由Map接口和Collection接口派生而来,Collection接口有两个

Java高级特性 第7节 多线程

一.进程与线程的概念 1. 进程 进程是应用程序的执行实例,有独立的内存空间和系统资源. 如上图,标红色的是一个Office Word进程. 进程的特点: 动态性:进程是动态的创建和消亡: 并发性:操作系统利用时间片轮转或其他策略让多个应用程序交替执行: 独立性:所有的进程都是独立运行的,系统会分别为这些线程分配资源和实施调度 2.  线程 CPU调度和分派的基本单位,进程中执行运算的最小单位,可完成一个独立的顺序控制流程. 如上图迅雷可以创建多个下载任务(每个下载任务可看做是一个线程),多个下

Java高级特性 第8节 网络编程技术

一.网络概述 1.网络的概念和分类 计算机网络是通过传输介质.通信设施和网络通信协议,把分散在不同地点的计算机设备互连起来,实现资源共享和数据传输的系统.网络编程就就是编写程序使联网的两个(或多个)设备(例如计算机)之间进行数据传输.Java语言对网络编程提供了良好的支持,通过其提供的接口我们可以很方便地进行网络编程.下面先对网络编程的一些基础知识进行介绍,最后给出使用Java语言进行网络编程的实例. 按照地理覆盖范围,计算机网络可以分为局域网(LAN).城域网(MAN).广域网(WAN). 2

Java高级特性 第11节 JUnit 3.x和JUnit 4.x测试框架

一.软件测试 1.软件测试的概念及分类 软件测试是使用人工或者自动手段来运行或测试某个系统的过程,其目的在于检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别.它是帮助识别开发完成(中间或最终的版本)的计算机软件(整体或部分)的正确度 .完全度和质量的软件过程. 软件测试过程: 2.软件测试的分类 按是否关心软件内部结构和具体实现角度来分: 黑盒测试(Black-box Testing) 黑盒测试也称功能测试,测试中把被测的软件当成一个黑盒子,不关心盒子的内部结构是什么,只关心软件的输入