JUC---13各种锁
一、公平锁与非公平锁
公平锁:加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得
非公平锁:加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待
非公平锁性能比公平锁高5~10倍,因为公平锁需要在多核的情况下维护一个队列。Java中的ReentrantLock 默认的lock()方法采用的是非公平锁。通过调用有参构造设置是否为公平与非公平锁
二、可重入锁(递归锁)
1.广义上的可重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁(前提得是同一个对象或者class),这样的锁就叫做可重入锁。ReentrantLock和synchronized都是可重入锁
2.特点:获取到外面的锁,就能拿到里面的锁(自动获取;就像自己家一样,拿钥匙开门之后,进卧室不用开锁)
3.代码:
- public class MyDemo {
- public static void main(String[] args) {
- testLock();
- }
- public static void testSynchronized() {
- Phone phone = new Phone();
- new Thread(() -> {
- phone.sms();
- }, "A").start();
- new Thread(() -> {
- phone.sms();
- }, "B").start();
- }
- public static void testLock() {
- Phone2 phone = new Phone2();
- new Thread(() -> {
- phone.sms();
- }, "A").start();
- new Thread(() -> {
- phone.sms();
- }, "B").start();
- }
- }
- class Phone {
- public synchronized void sms() {
- System.out.println(Thread.currentThread().getName() + "sms");
- call(); // 这里也有锁
- }
- public synchronized void call() {
- System.out.println(Thread.currentThread().getName() + "call");
- }
- }
- class Phone2 {
- Lock lock = new ReentrantLock();
- public void sms() {
- lock.lock(); // 细节问题:lock.lock(); lock.unlock(); // lock 锁必须配对,否则就会死在里面
- lock.lock();
- try {
- System.out.println(Thread.currentThread().getName() + "sms");
- call(); // 这里也有锁
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- lock.unlock();
- }
- }
- public void call() {
- lock.lock();
- try {
- System.out.println(Thread.currentThread().getName() + "call");
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
- }
三、自旋锁
1.是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。获取锁的线程一直处于活跃状态,但是并没有执行任何有效的任务,使用这种锁会造成busy-waiting。
2.在CAS中,Unsafe类里面的方法getAndAddInt()里面就是实现的自旋锁
代码:
- public class MyDemo {
- AtomicReference<Thread> atomicReference = new AtomicReference<>();
- // 加锁
- public void myLock() {
- Thread thread = Thread.currentThread();
- System.out.println(Thread.currentThread().getName() + "==> mylock");
- // 自旋锁
- while (!atomicReference.compareAndSet(null, thread)) {
- }
- }
- // 解锁
- public void myUnLock() {
- Thread thread = Thread.currentThread();
- System.out.println(Thread.currentThread().getName() + "==> myUnlock");
- atomicReference.compareAndSet(thread, null);
- }
- public static void main(String[] args) throws InterruptedException {
- MyDemo lock = new MyDemo();
- new Thread(() -> {
- lock.myLock();
- try {
- TimeUnit.SECONDS.sleep(5);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.myUnLock();
- }
- }, "T1").start();
- TimeUnit.SECONDS.sleep(1);
- new Thread(() -> {
- lock.myLock();
- try {
- TimeUnit.SECONDS.sleep(1);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.myUnLock();
- }
- }, "T2").start();
- }
- }
四、死锁
1.死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去
2.死锁产生的必要条件:
互斥条件、请求和保持条件、不剥夺条件、环路等待条件
3.死锁产生的原因:
竞争不可抢占性资源(或竞争可消耗资源)、进程推进顺序不当
4.避免与解决死锁的算法:死锁预防(有序资源分配法、银行家算法) 解决死锁(死锁预防、死锁避免、死锁检测和解除)
5.java中发生死锁的查看方式
1.运行发生死锁的代码
2.在程序运行时,使用 jps -l查看当前进程号
3.使用jstack 进程号找到死锁问题
JUC---13各种锁的更多相关文章
- Java并发编程(3) JUC中的锁
一 前言 前面已经说到JUC中的锁主要是基于AQS实现,而AQS(AQS的内部结构 .AQS的设计与实现)在前面已经简单介绍过了.今天记录下JUC包下的锁是怎么基于AQS上实现的 二 同步锁 同步锁不 ...
- Java - "JUC" ReentrantLock获取锁
[Java并发编程实战]-----“J.U.C”:ReentrantLock之一简介 ReentrantLock介绍 ReentrantLock是一个可重入的互斥锁,又被称为“独占锁”. 顾名思义,R ...
- Java - "JUC" ReentrantLock释放锁
Java多线程系列--“JUC锁”04之 公平锁(二) 释放公平锁(基于JDK1.7.0_40) 1. unlock() unlock()在ReentrantLock.java中实现的,源码如下: p ...
- JUC——线程同步锁(锁处理机制简介)
锁处理机制简介 juc的开发框架解决的核心问题是并发访问和数据安全操作问题,当进行并发访问的时候如果对于锁的控制不当,就会造成死锁这样的阻塞问题. 为了解决这样的缺陷,juc里面重新针对于锁的概念进行 ...
- iOS 13 绕过锁屏密码漏洞
iOS 13 很快就要发布了,在未正式发布之前,西班牙的安全研究员 Jose Rodriguez 公开了一个漏洞,能够查绕过锁屏密码查看通讯录.照片.短信. 在 iOS 设备上,当屏幕锁定时,用户无法 ...
- JUC(三):JUC包下锁概念
线程不安全集合类 ArrayList List是线程不安全的集合类,底层是Object数组实现,初始化容量是10(其实是一个空数组,第一次扩容时,将数组扩容为10),其后每次扩容大小为当前容量的一半( ...
- JUC之多线程锁问题
多线程锁 8种问题锁状态: 该部分全部围绕的是以下内容并结合相应的例子:synchronized实现同步的基础:Java中每个对象都可以作为锁. 具体表现为以下三种形式:(之前只是简单的了解) 对于普 ...
- JUC——线程同步锁(LockSupport阻塞原语)
java.util.concurrent.locks.LockSupport这个是一个独立的类,这个类的主要功能是用来解决Thread里面提供的suspend()(挂起线程).resume()(恢复运 ...
- JUC——线程同步锁(Condition精准控制)
在进行锁处理的时候还有一个接口:Condition,这个接口可以由用户来自己进行锁的对象创建. Condition的作用是对锁进行更精确的控制. Condition的await()方法相当于Objec ...
- JUC——线程同步锁(ReentrantReadWriteLock读写锁)
读写锁简介 所谓的读写锁值得是两把锁,在进行数据写入的时候有一个把“写锁”,而在进行数据读取的时候有一把“读锁”. 写锁会实现线程安全同步处理操作,而读锁可以被多个对象读取获取. 读写锁:ReadWr ...
随机推荐
- 基于redis的分布式锁的实现与框架解决方案
利用切面实现redis分布式锁:https://www.cnblogs.com/xiaoxiongcanguan/p/10718202.html 细节分析redis实现分布式锁的前因后果:https: ...
- Focal loss论文解析
Focal loss是目标检测领域的一篇十分经典的论文,它通过改造损失函数提升了一阶段目标检测的性能,背后关于类别不平衡的学习的思想值得我们深入地去探索和学习.正负样本失衡不仅仅在目标检测算法中会出现 ...
- Linux系统编程—信号集操作函数
先来回顾一下未决信号集是怎么回事. 信号从产生到抵达目的地,叫作信号递达.而信号从产生到递达的中间状态,叫作信号的未决状态.产生未决状态的原因有可能是信号受到阻塞了,也就是信号屏蔽字(或称阻塞信号集, ...
- 【题解】[SDOI2016]征途
Link 题目大意:给定序列,将它划分为\(m\)段使得方差最小,输出\(s^2*m^2\)(一个整数). \(\text{Solution:}\) 这题我通过题解中的大佬博客学到了一般化方差柿子的写 ...
- JVM 内存分配和占用
我们从一个简单示例来引出JVM的内存模型 简单示例 我从一个简单示例谈起这一块,我在看一篇文章的时候看到这么一个场景并且自己做了尝试,就是分配一个2M的数组,使用Xmx即最大内存为12M的话,会报错J ...
- spring-boot-route(十二)整合redis做为缓存
redis简介 redis作为一种非关系型数据库,读写非常快,应用十分广泛,它采用key-value的形式存储数据,value常用的五大数据类型有string(字符串),list(链表),set(集合 ...
- idea报“Cannot resolve symbol XXX”错误
解决方案
- mysql物理优化器代价模型分析【原创】
1. 引言 mysql的sql server在根据where condition检索数据的时候,一般会有多种数据检索的方法,其会根据各种数据检索方法代价的大小,选择代价最小的那个数据检索方法. 比如说 ...
- dockerfile镜像设置中文
一.dockerfile镜像设置中文 centos镜像默认不支持中文,把下面的内容加到dockerfile即可 # 修改时区 RUN rm -rf /etc/localtime && ...
- id+is+深浅co'p'y
day06 一.id.is 关键字:id #唯一的,如果id相同,说明2个变量指向同一个地址,就是变量一==变量二 注意:id相同值一定相同,值相同但是id不一定相同(不同代码块的值相同,他们就像太阳 ...