一、公平锁与非公平锁

  线程所谓的公平,就是指的是线程是否按照锁的申请顺序来获取锁,如果是遵守顺序来获取,这就是个公平锁,反之为非公平锁。

  非公平锁的优点在于吞吐量大,但是由于其不是遵循申请锁的顺序来获取锁,就会出现最开始申请的锁一直没有获取到,导致出现饥饿现象。

  java中的使用:

  synchronized:非公平锁

  ReentrantLock:按照其构造方法来指定该锁是否是公平锁,默认是非公平锁

二、共享锁与排他锁

  排他锁:该锁只能被一个线程使用;

  共享锁:该锁可被多个线程所使用;

  java中的使用:

  synchronized:排他锁(这是必然的)

  ReentrantLock:排他锁

  ReadWriteLock:ReadWriteLock中分为读写两个锁,其中读锁是共享锁,写锁是排他锁,这样的好处就是使得这个锁资源利用率高,因为只是读的话不会改变内容。

三、偏向锁、轻量级锁、重量级锁

  这三种只的是锁的状态,并且这三个锁只针对于synchronized

  偏向锁:当其他线程竞争时,才会释放的锁。这个锁的存在是因为获取锁和释放锁是非常浪费资源的,如果只有一个线程,偏向锁是非常好的一个选择。

  轻量级锁:当多线程任务是原子性操作时,可以同时让多个线程进入同步代码块。这锁是由偏向锁中从单线程变成多线程时演变的。

  重量级锁:当锁为轻量级锁的时候,另一个线程虽然是自旋,但自旋不会一直持续下去,当自旋一定次数的时候,还没有获取到锁,就会进入阻塞,该锁膨胀为重量级锁。重量级锁会让其他申请的线程进入阻塞,性能降低。

  在JDK5之前,synchronized一直都是重量级锁。

四、锁重入

  锁重入是指在多线程环境中,如果有两个线程A、B,且A、B两个线程都获取了同一把锁,如果此时只有A线程调用了B线程,A会自动获取B中的锁。锁重入的好处是能够避免死锁。

  synchronized与ReentrantLock都是锁重入。

五、自旋锁

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

六、死锁、活锁、饥饿

  这三个是线程的状态:

  死锁:当一个线程获取了锁,其他线程也来获取就会发生死锁

  活锁:当两个线程同时获取同一个资源,如果都发现了对方在获取这个资源,那么双方会停止访问又去同时访问另一相同资源,如此反复就产生了活锁。

  饥饿:优先级较低的线程无法执行

七、乐观锁与悲观锁

  悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。

  乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。

  java中的使用:

  悲观锁:synchronized

  乐观锁:JDK的原子性操作类java.util.concurrent.atomic

  

  

  

java并发学习第五章--线程中的锁的更多相关文章

  1. java并发学习--第六章 线程之间的通信

    一.等待通知机制wait()与notify() 在线程中除了线程同步机制外,还有一个最重要的机制就是线程之间的协调任务.比如说最常见的生产者与消费者模式,很明显如果要实现这个模式,我们需要创建两个线程 ...

  2. java并发学习--第三章 线程安全问题

    线程的安全问题一直是我们在开发过程中重要关注的地方,出现线程安全问题的必须满足两个条件:存在着两个或者两个以上的线程:多个线程共享着共同的一个资源, 而且操作资源的代码有多句.接下来我们来根据JDK自 ...

  3. java并发学习--第四章 JDK提供的线程原子性操作工具类

    在了解JDK提供的线程原子性操作工具类之前,我们应该先知道什么是原子性:在多线程并发的条件下,对于变量的操作是线程安全的,不会受到其他线程的干扰.接下来我们就学习JDK中线程的原子性操作. 一.CAS ...

  4. java并发学习--第八章 JDK 8 中线程优化的新特性

    一.新增原子类LongAdder LongAdder是JDK8中AtomicLong的增强工具类,它与AtomicLong最大的不同就是:在多线程场景下,LongAdder中对单一的变量进行拆分成多个 ...

  5. java并发学习--第七章 JDK提供的线程工具类

    一.ThreadLocal ThreadLocal类用于隔离多线程中使用的对象,为ThreadLocal类中传递的泛型就是要隔离的对象,简单的来说:如果我们在主线程创建了一个对象,并且需要给下面的多线 ...

  6. Java多线程学习(五)线程间通信知识点补充

    系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...

  7. java并发基础(五)--- 线程池的使用

    第8章介绍的是线程池的使用,直接进入正题. 一.线程饥饿死锁和饱和策略 1.线程饥饿死锁 在线程池中,如果任务依赖其他任务,那么可能产生死锁.举个极端的例子,在单线程的Executor中,如果一个任务 ...

  8. Java并发学习之中的一个——线程的创建

    本文是学习网络上的文章时的总结,感谢大家无私的分享. 1.与每一个Java语言中的元素一样,线程是对象.在Java中,我们有两种方式创建线程: a.通过直接继承thread类,然后覆盖run方法. b ...

  9. 《深入理解Java虚拟机》-----第13章 线程安全与锁优化

    概述 在软件业发展的初期,程序编写都是以算法为核心的,程序员会把数据和过程分别作为独立的部分来考虑,数据代表问题空间中的客体,程序代码则用于处理这些数据,这种思维方式直接站在计算机的角度去抽象问题和解 ...

随机推荐

  1. [CSP-S模拟测试]:array(单调栈)

    题目描述 在放完棋子之后,$dirty$又开始了新的游戏. 现在他拥有一个长为$n$的数组$A$,他定义第$i$个位置的分值为$i−k+1$,其中$k$需要满足: 对于任意满足$k\leqslant ...

  2. TypeScript快速笔记(一)

    刚学习TypeScript,但因为马上要用,主要是寻求先快速上手,而后再求精. 推荐学习网站: 1)https://www.runoob.com/typescript/ts-tutorial.html ...

  3. React-Native 之 GD (八)GET 网络请求封装

    1.到这里,相信各位对 React-Native 有所熟悉了吧,从现在开始我们要慢慢往实际的方向走,这边就先从网络请求这部分开始,在正式开发中,网络请求一般都单独作为一部分,我们在需要使用的地方只需要 ...

  4. docker-dnsmasq使用

    docker-dnsmasq支持通过web页面配置域名映射,镜像地址:https://hub.docker.com/r/jpillora/dnsmasq 使用步骤如下: 1.在Docker宿主上创建 ...

  5. xargs -i参数详解

    学习所需,文章转载过来! xargs与find经常结合来进行文件操作,平时删日志的时候只是习惯的去删除,比如 # find . -type f -name "*.log" | xa ...

  6. dojo 官方翻译 dojo/_base/array 版本1.10

    官方地址:http://dojotoolkit.org/reference-guide/1.10/dojo/_base/array.html#dojo-base-array array模块dojo进行 ...

  7. python -加密(MD5)

    import hashlib def md5_passwd(str,salt ='aaaaa') str = str + salt m = hashlib.md5()#构造一个MD5对象 m.upda ...

  8. 使用@Value注解对bean进行属性注入

    使用@Value注解,可以有三种属性注入的方式: 1. 使用字面量注入 2. 使用EL表达式注入 3. 使用占位符注入 import org.springframework.beans.factory ...

  9. mysql5.7.23性能调优之innodb_buffer_pool_size

    前言 我的数据库版本是5.7.23,最近发现执行SQL越来越慢,一条SQL语句执行需要将近30s. 对于原因,查询资料, https://www.cnblogs.com/qwangxiao/p/892 ...

  10. spring boot 将对象转换为json返回

    Spring Boot默认使用Jackson将对象转换为json,需要配置以下依赖: compile group: 'com.fasterxml.jackson.core', name: 'jacks ...