1、公平锁、非公平锁

公平锁:非常公平、不能插队、必须先来后到

  • 非公平锁:非常不公平、可以插队、(默认非公平)

    可以修改为公平锁

2、可重入锁

拿到外边的锁、就会自动拿到里边的锁。

package com.lock;

/**
* synchronized
*/
public class Demo1 {
public static void main(String[] args) {
Phone phone = new Phone(); 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"); }
}

使用lock锁

package com.lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* synchronized
*/
public class Demo1 {
public static void main(String[] args) {
Phone phone = new Phone(); new Thread(()->{
phone.sms();
},"A").start(); new Thread(()->{
phone.sms();
},"B").start();
}
} class Phone{ Lock lock = new ReentrantLock(); public void sms(){
lock.lock(); try {
System.out.println(Thread.currentThread().getName()+"sms");
call();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void call(){
lock.lock();
try {
System.out.println(Thread.currentThread().getName()+"call");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
} }
}

3、自旋锁

spinlock

自己写自旋锁

package com.lock;

import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference; public class SpinLockDemo { 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); } }
package com.lock;

import java.util.concurrent.TimeUnit;

public class Test {

    public static void main(String[] args) {
SpinLockDemo spinLockDemo = new SpinLockDemo(); new Thread(()->{
spinLockDemo.mylock(); try {
TimeUnit.SECONDS.sleep(3);
} catch (Exception e) {
e.printStackTrace();
} finally {
spinLockDemo.myunlock();
} },"A").start(); new Thread(()->{
spinLockDemo.mylock();
try {
System.out.println();
} catch (Exception e) {
e.printStackTrace();
} finally {
spinLockDemo.myunlock();
} },"B").start();
}
}

4、死锁

package com.lock;

import java.util.concurrent.TimeUnit;

public class DeadLockDemo {
public static void main(String[] args) {
String lockA="lockA";
String lockB ="lockB"; new Thread(new MyThread(lockA,lockB),"T1").start();
new Thread(new MyThread(lockB,lockA),"T2").start();
} } class MyThread implements Runnable{
private String lockA;
private String lockB; public MyThread(String lockA,String lockB){
this.lockA = lockA;
this.lockB =lockB;
} @Override
public void run() {
synchronized (lockA){
System.out.println(Thread.currentThread().getName()+"lock:"+lockA+"==>"+lockB);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockB){
System.out.println(Thread.currentThread().getName()+"lock:"+lockB+"==>"+lockA); }
}
}
}

测试

1、使用jps定位进程号jps -l


2、使用jstack 进程号

JUC(11)各种锁的理解(公平锁、可重入锁、自旋锁、死锁)的更多相关文章

  1. Java锁的种类以及辨析(二):自旋锁的其他种类

    作者:山鸡 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) .这些已经写好提供的锁为我们开发提供了便利,但是锁的具 ...

  2. java并发编程(一)可重入内置锁

    每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁.线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁.获得内置锁的唯一途径就是进入由这个锁保护的同步代码块 ...

  3. Redisson 分布式锁源码 01:可重入锁加锁

    前言 相信小伙伴都是使用分布式服务,那一定绕不开分布式服务中数据并发更新问题! 单系统很容易想到 Java 的各种锁,像 synchronize.ReentrantLock 等等等,那分布式系统如何处 ...

  4. 转:【Java并发编程】之一:可重入内置锁

    每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁.线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁.获得内置锁的唯一途径就是进入由这个锁保护的同步代码块 ...

  5. 【Java并发编程】之一:可重入内置锁

    每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁.线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁.获得内置锁的唯一途径就是进入由这个锁保护的同步代码块 ...

  6. 【分布式锁】Redis实现可重入的分布式锁

    一.前言 之前写的一篇文章<细说分布式锁>介绍了分布式锁的三种实现方式,但是Redis实现分布式锁关于Lua脚本实现.自定义分布式锁注解以及需要注意的问题都没描述.本文就是详细说明如何利用 ...

  7. JUC回顾之-可重入的互斥锁ReentrantLock

    1.什么是可重锁ReentrantLock? 就是支持重新进入的锁,表示该锁能够支持一个线程对资源的重复加锁. 2.ReentrantLock分为公平锁和非公平锁:区别是在于获取锁的机制上是否公平. ...

  8. java锁的种类以及辨析(一):自旋锁

    作者:山鸡 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) .这些已经写好提供的锁为我们开发提供了便利,但是锁的具 ...

  9. redis实现分布式锁需要考虑的因素以及可重入锁实现

    死锁 错误例子 解决方式  防止死锁 通过设置超时时间  不要使用setnx key   expire 20  不能保证原子性 如果setnx程序就挂了 没有执行expire就死锁了  reidis2 ...

  10. Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等

    Java 中15种锁的介绍 Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等,在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类 ...

随机推荐

  1. AgileFontSet迅捷字体设置程序

    AgileFontSet迅捷字体设置程序-用户手册  AgileFontSet的完整代码,参见 https://www.cnblogs.com/ybmj/p/11683291.html 1.程序特点和 ...

  2. Luogu1816 忠诚 (ST表)

    继续复习模板,加深理解ing... #include <iostream> #include <cstdio> #include <cstring> #includ ...

  3. Nodemon 如何实时监听 TypeScript 项目下的文件并热部署?

    首先你的项目要安装ts-node和nodemon: npm i -D ts-node nodemon 在package.json文件中配置运行脚本: "dev": "no ...

  4. vscode 插件 Cnblogs Client For VSCode

    目录 简介 主要功能 登录 / 授权 将本地 markdown 文件发布到博客园 博客园博文列表 将本地文件关联到博客园博文 拉取远程博文内容更新本地文件 图片上传 博文分类管理 导出 pdf 博文设 ...

  5. C++ 性能小测 1 二维数组的遍历效率

    C++ 性能小测 1 二维数组的遍历效率 遍历二维数组时,常规思路是使用一个嵌套循环.一方面,由于 CPU 使用了分支预测技术,因此通常将循环次数最多循环的放在最内层.另一方面,由于二维数组是按行存储 ...

  6. 简单创建一个SpringCloud2021.0.3项目(三)

    目录 1. 项目说明 1. 版本 2. 用到组件 3. 功能 2. 上俩篇教程 3. Gateway集成sentinel,网关层做熔断降级 1. 超时熔断降级 2. 异常熔断 3. 集成sentine ...

  7. 第六十八篇:vue-cli新建项目

    好家伙,之前只是一股脑得用,连里面的可选配置项都不清楚,今天来把它搞清楚 1.单页面应用 1.1.什么是单页面应用程序 单页面应用程序(英文名: Single Page Application)简称S ...

  8. SpringMVC 04: SpringMVC中4种页面跳转方式

    转发和重定向的页面跳转方式 页面跳转方式,本质上只有2种方式:转发 + 重定向 但在SpringMVC的具体实现上,转发可以细分为:普通的页面转发 + 经由action方法的页面转发 重定向可以细分为 ...

  9. PLSQL 与 PLPGSQL

    KingbaseES 为了更好地适应用户的oracle 应用,实现了对 plsql 的支持,用户可以根据需要使用 plsql 或 plpgsql. 以下简要介绍下二者的差异 一.格式差异 1.plpg ...

  10. 全能成熟稳定开源分布式存储Ceph破冰之旅-上

    @ 目录 概述 定义 传统存储方式及问题 优势 生产遇到问题 架构 总体架构 组成部分 CRUSH算法 数据读写过程 CLUSTER MAP 部署 部署建议 部署版本 部署方式 Cephadm部署 前 ...