java中锁的区别,JAVA锁有哪些

  java中锁的区别,JAVA锁有哪些

  

  如何解决写爬虫IP受阻的问题?立即使用。

  公平锁/非公平锁

  公平锁意味着多个线程按照它们申请锁的顺序获取锁。

  不公平锁是指多个线程获取锁的顺序与它们申请锁的顺序不一致。稍后应用的线程可能比最先应用的线程在获取锁方面具有更高的优先级。说不定,会造成优先级反转或者饿死。

  对于Java ReentrantLock,构造函数指定锁是否公平,默认为不公平。不公平锁的优点是吞吐量比公平锁大。

  对于Synchronized来说,也是一个不公平的锁。与通过AQS实现线程调度的ReentrantLock不同,没有办法使它成为一个公平锁。

  可重入锁

  重入锁,又称递归锁,是指当同一个线程在外层方法中获取锁时,内层方法会自动获取锁。有点抽象。下面是一个代码示例。

  对于Java ReentrantLock来说,它的名字可以看作是一个可重入锁,它的名字是ReentrantLock。

  对于Synchronized,它也是一个可重入锁。可重入锁的一个优点是可以在一定程度上避免死锁。

  同步的void setA()抛出异常{

  thread . sleep(1000);

  setB();

  }

  同步的void setB()抛出异常{

  thread . sleep(1000);

  }上面的代码是可重入锁的一个特性。如果不是可重入锁,setB可能不会被当前线程执行,这可能会导致死锁。

  独享锁/共享锁

  排他锁意味着锁一次只能被一个线程持有。

  共享锁意味着锁可以被多个线程持有。

  对于Java ReentrantLock,它是一个排他锁。但是对于锁的另一个实现类ReadWriteLock,它的读锁是共享锁,写锁是排他锁。

  读的共享锁可以保证并发读非常高效,读、写、读、写的进程互斥。

  排他锁和共享锁也是通过AQS实现的,用不同的方法实现排他锁或共享锁。

  对于Synchronized,当然是独占锁。

  互斥锁/读写锁

  上面说的排他锁/共享锁是一个广义的说法,互斥锁/读写锁是具体的实现。

  互斥锁在Java中的具体实现是ReentrantLock。

  读写锁在Java中的具体实现是ReadWriteLock。

  乐观锁/悲观锁

  乐观锁悲观锁不是指特定类型的锁,而是指并发和同步的角度。

  悲观锁认为同一数据的并发操作会被修改,即使没有修改,也会被认为修改。因此,对于相同数据的并发操作,悲观锁定采取锁定的形式。悲观地说,没有锁的并发操作肯定会出问题。

  乐观锁认为相同数据的并发操作不会被修改。在更新数据时,数据会通过尝试更新和不断重新更新来更新。乐观一点,并发操作不加锁没什么问题。

  从上面的描述可以看出,悲观锁适合写操作多的场景,乐观锁适合读操作多的场景。不锁会带来很多性能提升。

  悲观锁在Java中的使用就是利用各种锁。

  Java中乐观锁的使用是无锁编程,经常采用CAS算法。典型的例子是原子类,通过CAS spin更新原子操作。

  分段锁

  分段锁其实是一种锁的设计,并不是特定的锁。对于ConcurrentHashMap来说,并发的实现就是通过分段锁实现高效的并发操作。

  先用ConcurrentHashMap说一下段锁的含义和设计思路。ConcurrentHashMap中的段锁称为segment,是一种类似HashMap的结构(HashMap(JDK7和JDK8)的实现,即内部有一个Entry数组,数组中的每个元素都是一个链表;同时,它是一个ReentrantLock(段继承ReentrantLock)。

  当需要一个put元素时,并不是锁定整个hashmap,而是先通过hashcode知道它会放在哪个段中,然后锁定这个段,这样在进行多线程put时,只要不放在一个段中,就实现了真正的并行插入。

  但是在统计大小的时候,甚至在获取hashmap的全局信息的时候,都需要获取所有的分段锁来统计。

  分段锁的设计目的是细化锁的粒度。当操作不需要更新整个数组时,它只锁定数组中的一项。

  偏向锁/轻量级锁/重量级锁

  这三种锁指的是锁的状态,它们用于同步。在Java 5中,引入了锁升级机制来实现高效的同步。三个锁的状态由对象头中的对象监视器的字段指示。

  锁偏向意味着一段同步代码总是被一个线程访问,并且该线程将自动获得锁。降低获取锁的成本。

  轻量级锁是指当锁被另一个线程偏置访问时,偏置锁会升级为轻量级锁,其他线程会尝试以spin的形式获取锁,不会阻塞,提高性能。

  重量级锁意味着当锁是轻量级锁时,另一个线程旋转,但旋转不会永远持续。当锁旋转一定次数后,会进入一个街区,锁会膨胀成一个重量级的锁。重量级锁会阻塞其他应用程序线程并降低性能。

  自旋锁

  在Java中,自旋锁意味着试图获取锁的线程不会立即阻塞,而是以循环的方式尝试获取锁。这样做的好处是减少线程上下文切换的消耗,缺点是循环方式会消耗CPU。

  我们,大量免费的Java入门教程,欢迎在线学习!这就是java锁的区别。更多详情请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: