一、公平锁与非公平锁

  公平锁:加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得

  非公平锁:加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待

  非公平锁性能比公平锁高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各种锁的更多相关文章

  1. Java并发编程(3) JUC中的锁

    一 前言 前面已经说到JUC中的锁主要是基于AQS实现,而AQS(AQS的内部结构 .AQS的设计与实现)在前面已经简单介绍过了.今天记录下JUC包下的锁是怎么基于AQS上实现的 二 同步锁 同步锁不 ...

  2. Java - "JUC" ReentrantLock获取锁

    [Java并发编程实战]-----“J.U.C”:ReentrantLock之一简介 ReentrantLock介绍 ReentrantLock是一个可重入的互斥锁,又被称为“独占锁”. 顾名思义,R ...

  3. Java - "JUC" ReentrantLock释放锁

    Java多线程系列--“JUC锁”04之 公平锁(二) 释放公平锁(基于JDK1.7.0_40) 1. unlock() unlock()在ReentrantLock.java中实现的,源码如下: p ...

  4. JUC——线程同步锁(锁处理机制简介)

    锁处理机制简介 juc的开发框架解决的核心问题是并发访问和数据安全操作问题,当进行并发访问的时候如果对于锁的控制不当,就会造成死锁这样的阻塞问题. 为了解决这样的缺陷,juc里面重新针对于锁的概念进行 ...

  5. iOS 13 绕过锁屏密码漏洞

    iOS 13 很快就要发布了,在未正式发布之前,西班牙的安全研究员 Jose Rodriguez 公开了一个漏洞,能够查绕过锁屏密码查看通讯录.照片.短信. 在 iOS 设备上,当屏幕锁定时,用户无法 ...

  6. JUC(三):JUC包下锁概念

    线程不安全集合类 ArrayList List是线程不安全的集合类,底层是Object数组实现,初始化容量是10(其实是一个空数组,第一次扩容时,将数组扩容为10),其后每次扩容大小为当前容量的一半( ...

  7. JUC之多线程锁问题

    多线程锁 8种问题锁状态: 该部分全部围绕的是以下内容并结合相应的例子:synchronized实现同步的基础:Java中每个对象都可以作为锁. 具体表现为以下三种形式:(之前只是简单的了解) 对于普 ...

  8. JUC——线程同步锁(LockSupport阻塞原语)

    java.util.concurrent.locks.LockSupport这个是一个独立的类,这个类的主要功能是用来解决Thread里面提供的suspend()(挂起线程).resume()(恢复运 ...

  9. JUC——线程同步锁(Condition精准控制)

    在进行锁处理的时候还有一个接口:Condition,这个接口可以由用户来自己进行锁的对象创建. Condition的作用是对锁进行更精确的控制. Condition的await()方法相当于Objec ...

  10. JUC——线程同步锁(ReentrantReadWriteLock读写锁)

    读写锁简介 所谓的读写锁值得是两把锁,在进行数据写入的时候有一个把“写锁”,而在进行数据读取的时候有一把“读锁”. 写锁会实现线程安全同步处理操作,而读锁可以被多个对象读取获取. 读写锁:ReadWr ...

随机推荐

  1. 转载:python argparse用法总结

    https://www.jianshu.com/p/fef2d215b91d 1. argparse介绍 是python的一个命令行解析包,非常编写可读性非常好的程序 2. 基本用法 prog.py是 ...

  2. XXE漏洞介绍 & XXE漏洞攻击 & 修复建议

    介绍XXE漏洞 XML外部实体注入(XML External Entity)简称XXE漏洞,XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是-种允许用户对自己的标记语 ...

  3. mysql存储过程的初步学习及案例示例

    存储过程 几个月前小编开始初步接触学习存储过程,当然是跟着大神的视频学习的,在学习的过程中自己也记录了一下笔记,如今整理一下,接下来我将从概念,优缺点以及语法和实际应用几方面为大家详细讲解一下存储过程 ...

  4. 一篇文章搞定 Nginx 反向代理与负载均衡

    代理 要想弄明白反向代理,首先要知道啥是正向代理,要搞懂正向代理只需要知道啥是代理即可.代理其实就是一个中介,在不同事物或同一事物内部起到居间联系作用的环节.比如买票黄牛,房屋中介等等. 在互联网中代 ...

  5. Centos-挂载和卸载分区-mount

    mount 挂载和卸载指定的分区 相关选项 -a 加载文件 /etc/fstab中指定的所有设备 -n 不降加载信息记录在 /etc/mtab文件中 -r 只读方式加载设备 -w   可读可写价值设备 ...

  6. Python练习题 023:比后面的人大2岁

    [Python练习题 023] 有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁.问第4个人岁数,他说比第3个人大2岁.问第三个人,又说比第2人大两岁.问第2个人,说比第一个人大两岁.最后 问 ...

  7. makefile实验五 make clean rebuild 以及规则中的模式替换. 综合小小实验

    makefile代码: .PHONY : rebuild clean $(TARGET) #声明伪目标时,除直接使用目标名外, 也可以使用 $(变量) 这是取变量的值 CC := g++ TARGET ...

  8. Windows下安装VScode,并使用,以及中文配置

    转载:https://blog.csdn.net/x15011238662/article/details/85094006 首先明确一点,VScode是开发Go应用的基础编辑器,是Microsoft ...

  9. 《穷查理年鉴》诚实 & 希望 & 勇气 & 失败 & 改变(关于美好)

    诚实 013.自欺是最常见的欺骗. 038.毫无顾忌进行欺骗的人是无所畏惧的. 043.问心无愧者永无所惧. 068.诚实的人从欺诈人手中得到的买卖,我们从争论中得到真理. 134.没有欺骗就没有信任 ...

  10. 返回头添加cookie信息

    返回类型 HttpResponseMessage //构建返回对象 var res= Request.CreateResponse(HttpStstusCode.Ok,返回体) //创建cookie对 ...