【JUC】04-synchronized关键字

news2025/1/9 16:27:04

1. 悲观锁与乐观锁

  • 悲观锁:认为自己在使用数据的时候一定会有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改。synchroized和Lock的实现类都是
  • 乐观锁:认为自己在使用数据时不会有别的线程修改数据或资源,所以不会加锁。如果这个数据没有被更新,当前线程将自己修改的数据成功写入。如果数据已被修改,则根据自定义不同操作,比如放弃修改,重抢试锁。判断规则:1. 版本号机制Version、2. CAS算法,Java原子类中的递增操作就是通过CAS自旋实现

2. synchronized关键字

 synchronized锁的是整个资源类。同一时刻,只能有一个线程访问被synchronized修饰的方法。

// 线程操作资源类
class Phone{
    public synchronized void sendEmail() {
        System.out.println("sendEmail");
    }
    // 被synchronized修饰,同一时刻,只能允许一个线程访问类中的一个synchronized方法
    public synchronized void sendSMS() {
        System.out.println("sendSMS");
    }
    // 没有被synchronized修饰,多个线程可以同时访问
    public void hello() {
        System.out.println("Hello");
    }
}

public class demo02 {
    public static void main(String[] args) {
        Phone phone1 = new Phone();
        Phone phone2 = new Phone();
        new Thread(()->{
            phone1.sendEmail();
        }, "t1").start();

//        try {
//            TimeUnit.MILLISECONDS.sleep(200);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
        new Thread(()->{
            phone1.sendSMS();
            // phone2.hello();
            // phone1.sendSMS();
        }, "t2").start();
    }
}

 以下情况会先打印 Email :

// 线程操作资源类
class Phone{
    public synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("sendEmail");
    }
    public synchronized void sendSMS() {
        System.out.println("sendSMS");
    }
}

public class demo02 {
    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(()->{
            phone.sendEmail();
        }, "t1").start();

        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        new Thread(()->{
            phone.sendSMS();
        }, "t2").start();
    }
}

 先打印 SMS :

public static void main(String[] args) {
        Phone phone1 = new Phone();
        Phone phone2 = new Phone();
        new Thread(()->{
            phone1.sendEmail();
        }, "t1").start();

        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        new Thread(()->{
            // phone.sendSMS();
            // phone2.hello();
            phone2.sendSMS();
        }, "t2").start();
    }

 方法被static和synchronized修饰时,synchronized锁是类锁而不是实例锁,也即锁的是模板类。
 先打印 Email :

// 线程操作资源类
class Phone{
    public static synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("sendEmail");
    }

    public static synchronized void sendSMS() {
        System.out.println("sendSMS");
    }

    public void hello() {
        System.out.println("Hello");
    }
}

public class demo02 {
    public static void main(String[] args) {
        Phone phone1 = new Phone();
        // Phone phone2 = new Phone();
        new Thread(()->{
            phone1.sendEmail();
        }, "t1").start();

        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        new Thread(()->{
            // phone.sendSMS();
            // phone2.hello();
            phone1.sendSMS();
        }, "t2").start();
    }
}
public class demo02 {
    public static void main(String[] args) {
        Phone phone1 = new Phone();
        Phone phone2 = new Phone();
        new Thread(()->{
            phone1.sendEmail();
        }, "t1").start();

        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        new Thread(()->{
            // phone.sendSMS();
            // phone2.hello();
            phone2.sendSMS();
        }, "t2").start();
    }
}

  static synchronized锁的是Object模板类,synchronized锁是实例锁。两个不是同一把锁。
  打印SMS:

// 线程操作资源类
class Phone{
    public static synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("sendEmail");
    }

    public synchronized void sendSMS() {
        System.out.println("sendSMS");
    }

    public void hello() {
        System.out.println("Hello");
    }
}

public class demo02 {
    public static void main(String[] args) {
        Phone phone1 = new Phone();
        Phone phone2 = new Phone();
        new Thread(()->{
            phone1.sendEmail();
        }, "t1").start();

        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        new Thread(()->{
            // phone.sendSMS();
            // phone2.hello();
            phone2.sendSMS();
        }, "t2").start();
    }
}

    public static void main(String[] args) {
        Phone phone1 = new Phone();
        Phone phone2 = new Phone();
        new Thread(()->{
            phone1.sendEmail();
        }, "t1").start();

        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        new Thread(()->{
            // phone.sendSMS();
            // phone2.hello();
            phone1.sendSMS();
        }, "t2").start();
    }

在这里插入图片描述
 有两个monitorexit是为了防止出现异常,保证锁一定会被释放。代码中有抛异常的只会有一个monitorexit。
在这里插入图片描述

public class demo03 {
    Object o = new Object();
    Book book = new Book();

    // 一般来说,会有一个monitorenter和两个monitorexit。但在代码中,直接写throw异常,则只会有一个monitorenter和一个monitorexit
    public void test01() {
        /**
         * 任何一个对象都可以成为一个锁 class Book extends Object
         * 在HotSpot虚拟机中,monitor采用ObjectMonitor实现
         * 每个对象天生都带着一个对象监视器
         * 每一个被锁住的对象都会和 Monitor关系起来
         */
        synchronized (book) {
            System.out.println("Hello World");
        }
    }

    // 设置ACC_SYNCHRONIZED字段,会先持有锁,再执行方法
    public synchronized void test02() {
        System.out.println("Hello World");
    }

    // 设置ACC_STATIC, ACC_SYNCHRONIZED字段,判别是class锁,还是实例锁
    public static synchronized void test03() {
        System.out.println("Hello");
    }

    public static void main(String[] args) {
        System.out.println("Hello");
    }
}

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

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

相关文章

激光尘埃粒子计数器在洁净室监测中的关键应用(原理、类型、选型)

激光尘埃粒子计数器的应用 激光尘埃粒子计数器广泛应用于多个领域,包括但不限于: 权威机构:如血液中心、防疫站、疾控中心、质量监督所等。 生产企业和科研部门:如电子行业、制药车间、半导体、光学或精密机械加工、塑胶、喷漆…

构建流水线生产管理创新的RFID智能管理系统应用方案

在当今竞争激烈的制造业环境中,流水线生产的高效、精准和智能化管理已成为企业获取竞争优势的关键。然而,传统的流水线生产管理方式在应对日益复杂的生产需求和多变的市场环境时,逐渐暴露出诸多难点和痛点。 一、流水线生产管理的难点与痛点…

OCR调研

OCR调研 一、介绍 OCR(Optical Character Recognition,光学字符识别)是一种将图像中的文字转换为计算机可处理格式的技术。OCR技术经历了从传统OCR到基于深度学习的OCR的转变。深度学习OCR技术通过模拟人脑神经元结构处理文本和图像数据&am…

打造高效存储与访问体验:NFS共享携手Nginx负载均衡,赋能企业级数据流通与性能优化

作者简介:我是团团儿,是一名专注于云计算领域的专业创作者,感谢大家的关注 座右铭: 云端筑梦,数据为翼,探索无限可能,引领云计算新纪元 个人主页:团团-CSDN博客 目录: 前言&#…

AIGC实践|AI助力一张照片生成百变写真

前言: 在之前的文章中,我们已经领略了 AI 在动态有声绘本、小游戏开发、视频短片制作以及包装设计等领域的神奇应用,在本篇文章中,我将尝试利用AI辅助,使用一张照片生成个性化写真集。充分满足工作艺术照、各地郊游打…

关于自己部署AI大模型踩的坑(二)—— GPU篇

最近一直在研究如何打算属于我自己的J.A.R.V.I.S.(钢铁侠中的机器人管家)。 上一篇写了我最近在部署自己的大模型,使用llama3.1, 和通义千问2。虽然最终结果也是成功了,过程却十分地坎坷。 所以这一篇文章一是总结其中…

linux学习--第一天

--linux基础命令 -本地安装 1. sudo dpkg -i 软件包 :安装单个软件包 2. sudo dpkg -i * .deb :安装多个软件包 3. sudo dpkg -L 软件包:列出软件在系统中文件路径 4. sudo dpkg -s 软件包:列出软件包的安装状态 5. …

页面布局-1

1.定位 CSS 属性名功能属性值position设置定位 static:不定位,默认值。 relative:相对定位。 absolute:绝对定位。 fixed:固定定位 left与参照点左侧距离长度right与参照点右侧距离长度top与参照点上侧距离长度bottom…

【数据结构初阶】队列

hello! 目录 一、概念与结构 二、队列的实现 Queue.h Queue.c test.c 一、概念与结构 1、概念:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特性。 入队列:进行插入操作…

音视频概要

YUV原理的讲解 YUV是一种常见的视频像素格式,经常用在视频编解码上面,YUV分别由Y分量和U、V分量(红色投影Cr)组成。Y分量指的是亮度分量,也就是我们经常说的灰阶值,相当于一副灰色的图像。而U分量和V分量表示的是色度分量&#x…

搭建高可用OpenStack(Queen版)集群(九)之部署nova计算节点

一、搭建高可用OpenStack(Queen版)集群之部署计算节点 一、部署nova 1、安装nova-compute 在全部计算节点安装nova-compute服务 yum install python-openstackclient openstack-utils openstack-selinux -y yum install openstack-nova-compute -y 若yu…

基于vue框架的《大学计算机》课程思政资源共享平台ac9s7(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能:学生,教师,教研小组,章节分类,课程内容,资源类型,资源信息 开题报告内容 基于Vue框架的《大学计算机》课程思政资源共享平台 开题报告 一、引言 随着教育信息化的深入发展,高等教育领域对课程思政的重视程度日益提升。《大…

【kubernetes】pod控制器详解

一、pod控制器概述 1、Pod控制器作用 Pod控制器,是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试进行重启,当根据重启策略无效,则会重新新建pod的资源。 2、pod控制器…

Ethercat学习-SOEM主站源码解析(DC部分)

文章目录 SOEM DC模式源码简介示例用图ecx_porttimeecx_parentportecx_configdc如果从站不支持DC如果从站支持DC SOEM DC模式源码简介 示例用图 本文中都会围绕着这个图来讲,从站的port编号依次为0,3,1,2 在SOEM中,与…

C++11相关新特性(列表初始化、右值引用、可变参数模版)

目录 C11相关新特性 列表初始化 初始化简单变量 初始化容器 decltype关键字 C 11新增的容器 左值引用和右值引用 左值与右值 左值引用与右值引用 左值引用和右值引用的相互转化 右值引用的使用 拷贝构造函数与移动构造函数 赋值重载函数与移动赋值重载函数 元素插…

ZABBIX邮件监控发送信息

前言:本地邮箱,第三方邮箱,第三方邮箱加脚本 1、本地邮箱测试 #cd /home # ls laiyingx [rootzabbix ~]# vim /etc/postfix/main.cf /mydestination $myhostname, localhost.$mydomain, localhost,$mydomain [rootzabbix ~]# systemctl…

Python 函数返回yield还是return?这是个问题

如果你刚入门 Python,你可能之前没有遇到过yield。虽然它看起来很奇怪,但它是你编码工具库中的一个重要工具。在成为 Python 大师的道路上,你必须掌握它。 返回列表的函数 假设有一个函数,它可以一次性生成一系列值,…

代理服务器在HTTP请求中的应用:Ruby实例

摘要 在现代互联网架构中,代理服务器是不可或缺的组件,它提供了访问控制、数据加密、缓存和匿名访问等多种功能。本文将介绍代理服务器的基本概念,并以Ruby编程语言为例,展示如何在HTTP请求中使用代理服务器,包括设置…

树莓派4 AV没有视频输出

使用AV接口输出,没有画面 需要在config.txt文件中 增加配置 enable_tvout1config.txt 中的 dtoverlayvc4-kms-v3d 行末尾添加,composite: dtoverlayvc4-kms-v3d,composite默认情况下,输出 NTSC 复合视频。要选择不同的模式,请在…

python信息熵与信息增益

前言 最近在读几篇华为杯的优秀论文,都是关于数据预测相关的,准确来说是时间序列预测,在数据处理部分发现了一个有趣的内容“信息熵”,之前在周志华老师的西瓜书上决策树剪枝部分看到过,在数据降维的部分看到还是第一…