juc-2-锁应用/线程通信

news2025/2/2 0:46:11

目录

1 线程安全(库存超卖)

2 锁用法

2.1 同步方法

2.2.同步代码块

2.3 synchronized 作用于静态方法

总结

案例 静态成员变量 (synchronized锁非静态方法)

2.4ReentrantLock类是可重入、互斥、实现了Lock接口的锁

3 死锁产生与排查

4 线程间的(等待与通知机制)

5 原子性分类(原理需要分文章讲解太长)


1 线程安全(库存超卖)

1:多个线程对同一个变量做写的操作 。

2: 集群部署,多个服务对同一个变量做写的操作 (分布式锁)。等等

简单的小案例

public class ThreadRunnable implements Runnable{
    private  int  a=100;
    @Override
    public void run() {
       while (true){
           if(a>1){
             a--;
               System.out.println(Thread.currentThread().getName()+"=="+a);
           }
       }

    }
    public static void main(String[] args) {
        //同一个对象,同一变量 a
        ThreadRunnable thread = new ThreadRunnable();
        //两个线程分别减共享变量a
        new Thread(thread).start();
        new Thread(thread).start();
    }
}

 

多线程下变量的不可见性

在多线程并发执行下,多个线程修改共享的成员变量,会出现一个线程修改共享变量后,另一个线程,不能直接看到线程修改后的变量的最新值。

2 锁用法

2.1 同步方法

   由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,

    内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态

  注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类

 public synchronized void add(){}

2.2.同步代码块

被该关键字修饰的语句块会自动被加上内置锁,从而实现同步

注:同步是一种高开销的操作,因此应该尽量减少同步的内容。

    通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可

   synchronized(this){

    }

2.3 synchronized 作用于静态方法

总结

  1.  当synchronized作用于静态方法时,其锁就是当前类的class对象锁。由于静态成员不专属于任何一个实例对象,是类成员,因此通过class对象锁可以控制静态 成员的并发操作。
  2.  synchronized作用于非静态方法时,也可以直接锁类。也可以控制静态 成员的并发操作。
  3.  synchronized作用于非静态方法时,必须是同一个对象才能控制静态 成员的并发操作。

需要注意的是如果一个线程A调用一个实例对象的非static synchronized方法,而线程B需要调用这个实例对象所属类的静态 synchronized方法,是允许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的class对象,而访问非静态 synchronized 方法占用的锁是当前实例对象锁

案例 静态成员变量 (synchronized锁非静态方法)

   synchronized修饰非静态方法时,锁的是当前实例,不同实例就不是同一把锁了,就不是线程安全 

public class ThreadRunnable5 implements Runnable {
    private static int a = 100;
    @SneakyThrows @Override
    public void run() {
            while (true) {
                if (a > 1) {
                    increase4Obj();
                    Thread.sleep(100);
                }
            }
    }
    public synchronized   void increase4Obj(){
            System.out.println(Thread.currentThread().getName() + "==" + a);
            a--;
    }
    public static void main(String[] args) {
        ThreadRunnable5 thread = new ThreadRunnable5();
        new Thread(thread).start();
        new Thread(thread).start();
    }
}

普通方法锁的就是 对象的实例,不同的实例对象时,就是两个锁。无法保证线程安全

案例 静态成员变量 (synchronized锁静态方法 或 直接锁类)

2.4ReentrantLock类是可重入、互斥、实现了Lock接口的锁

        lock() : 获得锁

        unlock() : 释放锁

  注意及时释放锁,否则会出现死锁,通常在finally代码释放锁 

3 死锁产生与排查

死锁产生

public class ThreadRunnable3 implements Runnable {
    private int count = 1;
    private String locak = "aa";
    @SneakyThrows @Override
    public void run() {
        while (true) {
            count++;
            if (count % 2 == 0) {
                synchronized (locak) {
                    a();
                }
            } else {
                synchronized (this) {
                    b();
                }
            }
        }

    }
    public synchronized void a() {
        System.out.println("我是a方法" + Thread.currentThread().getName());
    }
    public void b() {
        synchronized (locak) {
            System.out.println("我是b方法" + Thread.currentThread().getName());
        }
    }

    public static void main(String[] args) {
        ThreadRunnable3 thread = new ThreadRunnable3();
        new Thread(thread).start();
        new Thread(thread).start();
    }
}

死锁排查

jdk安装目录 jdk1.8.0_341\bin\jconsole.exe

 

 

4 线程间的(等待与通知机制)

线程等待wait()和通知notify(),主要用于多线程之间的通信协作,而且这两个方法都是属于Object类,说明任何对象都可以调用这两个方法。

        当在一个实例对象上调用了wait()方法之后,当前线程就会在这个对象上等待。直到另外的线程调用了该对象的notify()方法,处于等待状态的线程才得以继续进行。

notifyAll(); 通知所有等待在该对象的线程。

        这样,多线程之间就可以用这两个方法进行通信协作了

 wait() 让出cup释放锁 这个方法一定注意,不要用if判断处理他的逻辑,不要用if判断处理他的逻辑,不要用if判断处理他的逻辑

写的不错的文章

wait()和notify()方法的使用_Morning sunshine的博客-CSDN博客_wait和notify的用法

wait()方法的注意点_EclipseO2的博客-CSDN博客

个人觉得了解即可。并没有太多应用场景,jdk8已经有很多api满足我们日常开发,线程间协作。了解原理即可。

5 原子性分类(原理需要分文章讲解太长)

1synchronized  jdk1.6开始,锁升级过程,偏向锁--->轻量级锁--->重量级锁

2Lock锁,需要自己实现锁的升级过程,底层基于aqs+cas实现

加锁时情况本地工作内存,获取主存上的最新值。 解锁时将新值刷新到主存里。

3ThreadLocal,需要注意内存泄漏。(但是高效)

4原子类CAS 非阻塞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/104245.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Hadoop实训任务3:HDFS和MapReduce综合操作

目录 1、启动Hadoop服务 2、创建文本文件 3、上传文本文件 4、显示文件内容 5、完成排序任务 6、计算最大利润和平均利润 7、统计学生总成绩和平均成绩 8、总结 1、启动Hadoop服务 在master虚拟机上执行命令: start-all.sh 启动hadoop服务进程 ​ ​ ​…

【嵌入式】构建嵌入式Linux系统(uboot、内核、文件系统)

知识架构及层次 Linux内核由三部分构成: Bootloader:启动引导系统(可执行文件)Kernel:内核(可执行文件)Root File System:根文件系统嵌入式Linux系统构成及启动略析 嵌入式 Linux …

Java八股文,YYDS!字节最新秋招面试题,“死记”这些你也可以斩获字节offer

Java 一面基本上都是基础题,同样是 CURD 的活,谁更熟练要谁,比如下面这些面试题,八股文越熟练越容易通过 Java 面试。 下面会给大家详解的介绍一下每个技术点的必问问题! 一、Java 基础 1.JDK动态代理和CGLIB动态代…

C++图像的形态学操作

什么是图像的形态学操作? 使用数学形态学的基本运算,由计算机对图像进行分析,以达到所需结果的一种技术。 形态学,morphology, 形态学最初是生物学中研究动物和植物结构的一个分支,被引入图像处理领域后,图…

C语言 期末合集 pta

6-1 求最大的偶数和最小的奇数的差 分数 10 全屏浏览题目 切换布局 作者 王跃萍 单位 东北石油大学 求10个数中的最大的偶数和最小的奇数的差。 函数接口定义: int fun(int a[],int n); 函数fun中a、n是用户传入的参数,函数fun的功能是求a数组中的…

【LVGL学习笔记】(五)使用SquareLine Studio设计UI

LVGL全程LittleVGL,是一个轻量化的,开源的,用于嵌入式GUI设计的图形库。并且配合LVGL模拟器,可以在电脑对界面进行编辑显示,测试通过后再移植进嵌入式设备中,实现高效的项目开发。 LVGL中文教程手册&#…

点云地图构建及定位

点云地图构建及定位1. 回环检测1.1 基于Scan Context1.2 基于直方图2. 后端优化2.1 后端优化基本原理2.2 李群、李代数基本知识2.3 李群、李代数基本知识2.3.1 SO(3)\mathrm{SO}(3)SO(3) 对应的 BCH\mathrm{BCH}BCH 公式2.3.2 SE(3)\mathrm{SE}(3)SE(3) 对应的 BCH\mathrm{BCH}…

链式存储之:链表的引出及其简介

上篇博客,笔者讲解了一下顺序表ArrayList,对于ArrayList有想法的各位老铁可以看一下:值得思索的:ArrayList和线性表,你确定错过这次机会_念君思宁的博客-CSDN博客值得思索的:ArrayList和线性表,…

Html5 canvas创意特效合集

Canvas就像一块画布,我们可以通过调用脚本在Canvas上绘制任意形状,甚至是制作动画。本文就是收集了很多非常富有创意的一些canvas动画特效例子,这些例子都非常适合大家学习。 1.3D篝火动画特效 这款篝火特效是基于 three.js 和 canvas 制作的…

博实结将在创业板上会:计划募资25亿元,周小强为实际控制人

近日,深圳市博实结科技股份有限公司(下称“博实结”)在深圳证券交易所递交招股书(上会稿),准备在创业板上市。据贝多财经了解,博实结将于2022年12月23日接受创业板上市委审议,一同上…

Vue3----props和emit的使用

作用:父组件通过 props 向下传递数据给子组件; 用途:当有一种类型的组件需要被使用多次,每一次的调用都只是特定的地方不同,就好像一张个人简介表,每次填的人的信息都不同,但是结构都是一样的。…

Nacos学习笔记 (2)Nacos基础核心特性

内容: Nacos架构及其核心特性,包括服务注册、服务发现、发布与获取配置特性,以及Nacos Spring关键特性。 本文内容,参考 Nacos 官网与 《Nacos架构&原理》一书。 1. Nacos 架构 详情推荐参考: (1&a…

服务器取证——服务器基础知识

目录 一、服务器基本介绍 (一)概念 (二)构成 (三) 种类 (四)与pc区别 二、 磁盘阵列RAID (一)概念 (二)产生原因 &#xff0…

【Django】第二课 银行账户管理系统开发

概念 本文在上一篇文章基础之前进行构建和完善 账户信息的分页显示 用户通过点击首页的“查询账户”,进入账户信息查询页面 则点击该按钮触发点击事件,向django服务器发出请求 接着我们在urls.py中需要定义与该地址进行匹配的地址,并匹配后…

Java on VS Code 12月更新年度亮点回顾|实时内存视图、注入处理器支持与用户体验改进

作者:Nick Zhu - Senior Program Manager, Developer Division at Microsoft 排版:Alan Wang 大家好,一年的时间过得很快,我们已经来到了2022年的年底。回顾 2022 年,我们的产品也经历了很多的迭代,在此之中…

甲氧基聚乙二醇二苯并环辛烯mPEG-DBCO简介DBCO-mPEG科研实验用试剂

中文名:甲氧基聚乙二醇二苯并环辛烯 英文名:mPEG-DBCO;DBCO-mPEG 分子量: 1K.2K.5K.10k.20k.30k 溶解度: DMSO, DMF 储存条件: -20C 状态:淡黄色到白色固体,或者半固体,取决于分子量。 溶解性&#x…

网心科技马婷:探寻边缘计算的“诗和远方”

​​LiveVideoStackCon 2022上海站活动结束,每一次大会的举办对音视频领域都是新的洗礼,同时也带来了新的收获和挑战。随着音视频技术在各种行业、场景中的逐渐成熟,更多的业务形态、产品变换 、跨界案例等越来越多的部分值得我们探寻和研究。…

「网络工程师必会技能」-路由器介绍和路由器基本配置

「网络工程师必会技能」-路由器介绍和路由器基本配置,这是每个网络必须会的技能,不是你有证书就一个网络工程师了哦! 以Cisco路由器为例说明: (1)访问路由器。访问路由器与访问交换机一样,可以…

医院陪护小程序,专业的事情交给专业的人

陪诊服务这几年一直受到人们的好评,有了医院陪护小程序之后一些无法居家照顾老人的子女可以通过小程序为老人预约服务,陪诊平台的出现还让陪诊员有了正规的接单平台,不仅方便了人们下单找陪诊员还可以对陪诊人员坐正规的管理。那么在开发医院…

33.前端笔记-CSS3-2D转换

目录1、转换2、二维坐标系2.1 2D转换之移动translate2.2 2D旋转之rotate练习1练习2练习32.3 2D转换之缩放scale练习1练习22D转换综合写法转换综合练习1、转换 转换transform是CSS3中具有颠覆性的特征之一,可以实现元素的位移、旋转、缩放等效果 2、二维坐标系 2.…