方法锁,对象锁,类锁的区别和用法

2023-11-03

在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看这个关键字的用法。

因为synchronized关键字涉及到锁的概念,所以先来了解一些相关的锁知识。

 

java的内置锁:每个java对象都可以用做一个实现同步的锁,这些锁成为内置锁。线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁。获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法。

 

java内置锁是一个互斥锁,这就是意味着最多只有一个线程能够获得该锁,当线程A尝试去获得线程B持有的内置锁时,线程A必须等待或者阻塞,知道线程B释放这个锁,如果B线程不释放这个锁,那么A线程将永远等待下去。

 

java的对象锁和类锁:java的对象锁和类锁在锁的概念上基本上和内置锁是一致的,但是,两个锁实际是有很大的区别的,对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的class对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的

synchronized 
在修饰代码块的时候需要一个reference对象作为锁的对象. 
修饰方法的时候默认是当前对象作为锁的对象. 
修饰类时候默认是当前类的Class对象作为锁的对象.

线程同步的方法:sychronized、lock、reentrantLock分析 

上面已经对锁的一些概念有了一点了解,下面探讨synchronized关键字的用法。

 synchronized的用法:synchronized修饰方法和synchronized修饰代码块。


一、对象锁(方法锁)实例与分析

  类中非静态方法上的锁;用this做锁;


二、类锁实例与分析

    类中静态方法上的锁;用XXX.class做锁;


三、引用对象作为锁,代码块实例与分析

     用类中的成员变量引用做锁;


欠下的实例,今天补充一下。。。偷个懒,写到一个类中了,就不逐个写了

package com.steve.locks;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SynchronizedTest {
    private static int i=0;

    public int getI()throws Exception{
        i++;
        Thread.sleep(100);
        return i;
    }
    /**
     * @Author Loujitao
     * @Date 2018/6/29
     * @Time  14:16
     * @Description:
     * 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁
     */
    public synchronized int getI1()throws Exception{
        i++;
        Thread.sleep(100);
        return i;
    }
    /*
    修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
    * */
    public synchronized static int getI2()throws Exception{
        i++;
        Thread.sleep(100);
        return i;
    }
    /*
    修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
    * */
    public int getI3(Object o)throws Exception{
        synchronized (o){
            i++;
            Thread.sleep(100);
            return i;
        }
    }

    public static void main(String[] args) {
        //实例化本类实例,调用普通方法是用到。
        final SynchronizedTest syt=new SynchronizedTest();
        //创建了一个最大容量为5的线程池
        ExecutorService es= Executors.newFixedThreadPool(5);
        //这里的lock对象,是用作锁代码块是用的,做为所对象  别用字符串常量做锁;锁对象引用改变,会引发change锁事件,即立即释放锁
        final Object lock=new Object();

        for (int i=1;i<10;i++){
            es.execute(new Runnable() {
                @Override
                public void run() {
                   try {
                       System.out.println(syt.getI());//调用非安全的方法
//                       System.out.println(syt.getI1());//调用加锁了的对象方法
//                       System.out.println(SynchronizedTest.getI2());//调用加锁的静态方法
//                       System.out.println(syt.getI3(lock));//调用调用锁代码块的方法
                  } catch (Exception e) {
                      e.printStackTrace();
                 }
             }
            });
        }
        es.shutdown();
    }
}

下面是运行结果:

    非安全的方法:

加锁的三种方法:




sychronized使用场景(这些场景,大致能囊括锁使用的大部分情况,有兴趣的可以尝试写写每个案例)

1、一个类的对象锁和另一个类的对象锁是没有关联的,当一个线程获得A类的对象锁时,它同时也可以获得B类的对象锁。

2、一个类中带对象锁的方法和不带锁的方法,可以异步执行,不干扰,不需要等待。

3、一个类中,如果set()方法加了对象锁,get()方法不加对象锁,容易发生数据脏读。可以用类锁或者set、get都加对象锁,解决。

4、同一个类中,多个锁方法相互调用,线程安全。锁重入,获取锁的对象调用加锁的方法时,会自动获取对象锁,不需要等待。

5、父子类中,锁方法相互调用,线程安全。锁重入,在继承关系中适用。

6、锁方法发生异常时,会自动释放锁。程序继续执行,如果没有响应的处理,会发生业务逻辑的漏洞或者混乱。多见批处理、消息队列等。

7、类中的object成员变量加锁,为任意对象锁。

8、String常量值加锁,容易发生死锁。

9、change锁情况的发生,如果你在一个对象锁方法中,对这个锁对象的引用做了修改,则表示释放了锁对象。如重新new object(),赋值给这个锁对象。但是锁对象的属性或值发生改变,并不发生锁的释放。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

方法锁,对象锁,类锁的区别和用法 的相关文章

  • 方法锁,对象锁,类锁的区别和用法

    在java编程中 经常需要用到同步 而用得最多的也许是synchronized关键字了 下面看看这个关键字的用法 因为synchronized关键字涉及到锁的概念 所以先来了解一些相关的锁知识 java的内置锁 每个java对象都可以用做一
  • java.util.concurrent.locks.ReentrantReadWriteLock 读写锁

    读写锁简介 对共享资源有读和写的操作 且写操作没有读操作那么频繁 在没有写操作的时候 多个线程同时读一个资源没有任何问题 所以应该允许多个线程同时读取共享资源 但是如果一个线程想去写这些共享资源 就不应该允许其他线程对该资源进行读和写的操作
  • MPI测试程序

    include
  • java中Synchronized和Lock的区别

    Synchronized和Lock的区别 原始构成 synchronized关键字属于JVM层面的 通过monitorenter monitorexit指令实现 底层是通过monitor对象来完成 其实wait notify等方法也依赖mo
  • 理解什么是 JMM

    理解什么是 JMM 本文已收录至 GitHub https github com yifanzheng java notes Java 虚拟机是一个完整的计算机的一个模型 因此这个模型自然也包含一个内存模型 Java 内存模型 也就是说 J
  • 多线程-Thread类的常用方法及使用场景

    众所周知 操作线程就必须熟读线程的API方法 万一你开个多线程刹不住车就歇菜了 下面就介绍一些API基本用法 包括sleep join yield interrupt sleep 让当前线程睡一会 原生用法Thread sleep 毫秒 会
  • 场景题之最快返回结果

    场景题之最快返回结果 问题描述 输入中文 最快从百度翻译 谷歌翻译 有道翻译获取结果返回 代码实现 思路 采用CompletableFuture实现 多个CompletableFuture可以串行执行 也可以并行执行 其中anyOf 方法只
  • synchronized与(ReentrantLock)Lock的对比区别

    类别 synchronized Lock 存在层次 Java关键字 属于原生语法层面 需要jvm实现 而Lock它是JDK 1 5之后提供的API层面的互斥锁 需要lock 和unlock 方法配合try finally语句块来完成 锁的释
  • Callable接口详解

    Callable接口详解 Callable 返回结果并且可能抛出异常的任务 优点 可以获得任务执行返回值 通过与Future的结合 可以实现利用Future来跟踪异步计算的结果 Runnable和Callable的区别 1 Callable
  • JUC学习笔记及拓展

    本文为自己整理的学习笔记及学习心得 大纲取自尚硅谷的JUC视频 感兴趣的小伙伴可以去B站自学 JUC学习笔记及拓展 Java JUC 1 Java JUC简介 2 volatile 关键字 内存可见性 2 1 内存可见性 2 2 volat
  • 并发策略之分工原则

    本文主要思想来自 Java虚拟机并发编程 薛笛 译 为什么要用并发 并发是再在有限的资源下提高性能的有效手段 当然现在互联网环境下并发访问的现象也比比皆是 但是本文并不涉及处理并发访问 而是使用并发手段解决复杂任务的策略 另外关于并发和并行
  • Java并发之锁

    Java并发之锁 一 临界区 二 线程安全 三 解决临界区线程安全问题 四 Java对象头 五 重量级锁 Monitor 5 1 synchronized 5 1 1 synchronized加锁流程 六 轻量级锁 6 1 轻量级锁加锁流程
  • AQS原理解析及源码分析

    目录 1 介绍下AQS几个重要的组件 2 内部成员变量state 3 同步队列NODE 4 等待队列 condition AbstractQueuedSynchronizer又称为队列同步器 后面简称AQS AQS的核心思想是 如果被请求的
  • QT多线程基础

    文章目录 简介 相关名词 QT 运行方式 基础使用方法 void QObject moveToThread QThread targetThread 退出线程过程 wait 等待子线程的结束 实例 QT锁QMutex QMutexLocke
  • Semaphore 源码分析

    需要提前了解的知识点 AbstractQueuedSynchronizer 实现原理 类介绍 Semaphore 信号量 是用来控制同时访问特定资源的线程数量 它通过协调各个线程 以保证合理的使用公共资源 比如控制用户的访问量 同一时刻只允
  • Lock锁

    Lock实现提供比使用synchronized方法和语句可以获得的更广泛的锁定操作 它们允许更灵活的结构化 可能具有完全不同的属性 并且可以支持多个相关联的对象Condition 1 传统的synchronized package cn d
  • 深入理解synchronized底层原理,一篇文章就够了!

    文章目录 前言 一 synchronized的特性 1 1 原子性 1 2 可见性 1 3 有序性 1 4 可重入性 二 synchronized的用法 三 synchronized锁的实现 3 1 同步方法 3 2 同步代码块 四 syn
  • 进程、线程、管程、纤程、协程概念以及区别

    进程 进程是指在操作系统中能独立运行并作为资源分配的基本单位 由一组机器指令 数据和堆栈等组成的能独立运行的活动实体 进程在运行是需要一定的资源 如CPU 存储空间和I O设备等 进程是资源分配的基本单位 进程的调度涉及到的内容比较多 存储
  • CountDownLatch、CyclicBarrier、Semaphore源码解析

    1 CountDownLatch 计数器 CountDownLatch CountDownLatch 类位于java util concurrent包下 利用它可以实现类似计数器的功能 比如有一个任务A 它要等待其他4个任务执行完毕之后才能
  • 并发编程4 - 线程状态、死锁及ReentrantLock

    文章目录 一 再述线程状态转换 二 多把锁与线程活跃性问题 1 多把锁 2 活跃性 三 ReEntrantLock 1 基本用法 2 可重入 3 可打断 4 锁超时 5 公平锁 6 条件变量 一 再述线程状态转换 情况1 New RUNNA

随机推荐

  • 静态时序分析——基础概念

    一 简述 静态时序分析是检查系统时序是否满足要求的主要手段 以往时序的验证依赖于仿真 采用仿真的方法 覆盖率跟所施加的激励有关 有些时序违例会被忽略 此外 仿真方法效率非常的低 会大大延长产品的开发周期 静态时序分析工具很好地解决了这两个问
  • Java的冒泡排序方法

    废话不多说 直接上代码 看不懂的话可以看注释 在这里插入代码片 public static void bubbleSort int arr 标志位 标志是否进行交换 boolean flag false for int i 0 i lt a
  • java 双列集合Map 万字详解

    目录 一 前言 二 概述 三 特点 四 常用方法 1 V put K key V value 代码演示 2 V get Object key 代码演示 3 V remove Object key 代码演示 4 int size 代码演示 5
  • excel两个指标相关性分析_指数相关性如何计算?

    且慢上长赢指数计划中有个指标叫相关性 这是统计学概念 主要看两个数列之间的相关程度 用在指数投资上 用作分散参照 如果两只指数的相关性越高 说明指数走势高度相似 涨的时候都涨 跌的时候都跌 起不到平衡或者分散风险的目的 因而 在投资时 尽量
  • 力扣 - 106、从中序与后序遍历序列构造二叉树

    题目 根据一棵树的中序遍历与后序遍历构造二叉树 注意 你可以假设树中没有重复的元素 例如 给出 中序遍历 inorder 9 3 15 20 7 后序遍历 postorder 9 15 7 20 3 返回如下的二叉树 3 9 20 15 7
  • 活锁和饥饿

    活锁 活锁本质上不是锁 是互相干扰导致线程无法跳出循环 比如 public class TestLiveLock static volatile int count 10 static final Object lock new Objec
  • SpringBoot 自定义注解(一)参数校验

    SpringBoot 2 3 0版本之后就没有引入validation对应的包 需要手动引用 依赖如下
  • ​JVM-调优参数归纳​

    本地线程分配缓冲 XX UseTLAB 把内存分配的动作按照线程划分在不同的空间之中进行 即每个线程在Java堆中预先分配一小块内存 通过 XX UseTLAB参数来设定虚拟机是否使用TLAB JVM会默认开启 XX UseTLAB XX
  • moviepy剪切视频&spleeter视频降噪-CPU&GPU

    文章目录 简介 安装spleeter 代码执行 简介 moviepy官方中文API spleeter官方github 本文视频降噪原理为使用spleeter提取出人声 仅将人声写回视频并保存 对于AudioClip和VideoClip使用完
  • 三分钟带你了解ES【详解版】

    1 ES是什么 Elasticsearch 是一个分布式的 RESTful 搜索和分析引擎 可用来集中存储您的数据 以便您对形形色色 规模不一的数据进行搜索 索引和分析 上面是 官网 API文档 对的定位描述 ES 是一个分布式的搜索引擎
  • 使用机器学习和深度学习技术预测股票价格

    介绍 预测股市的走势是最困难的事情之一 影响预测的因素很多 包括物理因素与心理因素 理性行为和非理性行为等 所有这些因素结合在一起共同导致股价波动 很难以高精度预测 我们是否可以将机器学习作为该领域的游戏规则改变者吗 利用一些特性 比如关于
  • java为什么需要枚举_java – 什么是枚举,为什么它们有用?

    当变量 特别是方法参数 只能从一组可能的值中取出一个时 应该总是使用枚举 示例将是类型常量 合同状态 永久 临时 学徒 或标志 立即执行 延迟执行 如果使用枚举而不是整数 或字符串代码 则增加了编译时检查 避免传入无效常量的错误 并记录哪些
  • 隐私政策

    本应用尊重并保护所有使用服务用户的个人隐私权 为了给您提供更准确 更有个性化的服务 本应用会按照本隐私权政策的规定使用和披露您的个人信息 但本应用将以高度的勤勉 审慎义务对待这些信息 除本隐私权政策另有规定外 在未征得您事先许可的情况下 本
  • linux安装MQ(rabbitMQ)

    1 首先我们需要对应的安装包 没有的私信我 将安装包放到opt目录下 rpm ivh erlang的安装包 rpm ivh socat的安装包 rpm ivh rabbitmq的安装包 2 启用管理插件 rabbitmq plugins e
  • vue.js使用v-model父子组件双向传值

    父子组件双向传值 vue是单向数据流机制 v mode在组件中的双向传值的原理等同于触发了input事件
  • Teamviewer被判定为商用的解决办法(未解决)

    我是看了这个博客开始尝试 我会在他的基础上做一些补充https www jianshu com p c1a77c351283 主旨 改ID 1 安装13版本的teamviewer 查看是否是13version的Teamviewer 如果不是
  • 黑科技抢先尝(续) - Windows terminal中WSL Linux 终端的极简美化指南

    之前 本人写了两篇文章 黑科技抢先尝 Windows全新终端初体验 附代码Build全过程 和 程会玩 无需自行编译也能玩转 Windows Terminal 介绍了玩转Windows terminal的两种方式 今天这篇文章 主要介绍如何
  • 如何画出广义表的存储结构

    这部分王道书没有提到 但是自主命题的学校考过这种题 为了方便自己复习 所以写的方法比较通俗 方便理解 例 画出广义表 a x y x 的存储结构 分析 可以这么理解 1 一个完整的括号相当于一个节点 一个字母也是 2 括号内的东西 都是它的
  • 【Cross-Chain】Xscope 跨链交易攻击检测

    本次解读的文章是 2022 年发表于 ASE IEEE ACM International Conference on Automated Software Engineering 的跨链交易攻击检测论文 本篇论文首先对跨链交易的工作流进行
  • 方法锁,对象锁,类锁的区别和用法

    在java编程中 经常需要用到同步 而用得最多的也许是synchronized关键字了 下面看看这个关键字的用法 因为synchronized关键字涉及到锁的概念 所以先来了解一些相关的锁知识 java的内置锁 每个java对象都可以用做一