(三) 共享模型之管程【共享带来的问题】

news2024/11/26 18:23:28

一、共享带来的问题

1. 临界区

(1)一个程序运行多个线程本身是没有问题的

(2)问题出在多个线程访问共享资源

1️⃣多个线程读共享资源其实也没有问题

2️⃣在多个线程对共享资源读写操作时发送指令交错,就会出现问题

(3)一段代码块内如果存在对共享资源的多线程读写操作,称这段代码块为临界区

2. 竞态条件 Race Condition

多个线程在临界区内执行,由于代码的执行序列不同而导致结果无法预测,称之为发生了竞态条件

二、Synchronized 解决方案(P54)

1. 应用之互斥

为了避免临界区的竞态条件发生,有多种手段可以达到目的。

(1)阻塞式的解决方案:synchronized、Lock

(2)非阻塞式的解决方案:原子变量

synchronized,即俗称的【对象锁】,它采用互斥的方式让同一时刻至多只有一个线程能持有对象锁,其他线程再想获取这个对象锁时就会阻塞住。这样就能保证拥有锁的线程可以安全的执行临界区内的代码,不用担心线程上下文切换。

注意:

虽然 Java 中互斥和同步都可以采用 synchronized 关键字来完成,但有区别:

(1)互斥是保证临界区的竞态条件发生,同一时刻只能有一个线程执行临界区代码。

(2)同步是由于线程执行的先后顺序不同,需要一个线程等待其他线程运行到某个点。

2. synchronized

synchronized(对象) // 线程1, 线程2(blocked)
{
     临界区
}
@Slf4j(topic = "c.Test17")
public class Test17 {
    static int counter = 0;
    static Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                synchronized (lock) {
                    counter++;
                }
            }
        },"t1");

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                synchronized (lock) {
                    counter--;
                }
            }
        },"t2");

        t1.start();
        t2.start();
        t1.join();
        t2.join();
        log.debug("{}",counter);

    }
}

思考:

synchronized 实际是用对象锁保证了临界区内代码的原子性,临界区内的代码对外是不可分割的,不会被线程切换所打断。

3. 面向对象改进

@Slf4j(topic = "c.Test17")
public class Test17 {
    public static void main(String[] args) throws InterruptedException {
        Room room = new Room();
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                room.increment();
            }
        }, "t1");

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                room.decrement();
            }
        }, "t2");

        t1.start();
        t2.start();
        t1.join();
        t2.join();
        log.debug("{}", room.getCounter());
    }
}

class Room {
    private int counter = 0;

    public synchronized void increment() {
        counter++;
    }

    public synchronized void decrement() {
        counter--;
    }

    public synchronized int getCounter() {
        return counter;
    }
}

三、方法上的 synchronized(P59)

(1)普通方法 

(2) 静态方法  

 (3)不加 synchronized 的方法

不加 synchronzied 的方法就好比不遵守规则的人,不去老实排队(好比翻窗户进去的)

四、变量的线程安全分析(P63)

1. 成员变量和静态变量是否线程安全?

(1)如果它们没有共享,则线程安全

(2)如果它们被共享了,根据它们的状态是否能否改变,又分两种期刊

1️⃣如果只有读操作,则线程安全

2️⃣如果有读写操作,则这段代码是临界区,需要考虑线程安全

2. 局部变量是否线程安全?

(1)局部变量是线程安全的

(2)但局部变量引用的对象则未必

1️⃣如果该对象没有逃离方法的作用范围,它是线程安全的

2️⃣如果该对象逃离方法的作用范围,需要考虑线程安全

3. 常见线程安全类

String

包装类(Integer 等)

StringBuffer

Random

Vector

Hashtable

java.util.concurrent 包下的类

这里说它们是线程安全的是指,多个线程调用它们同一个实例的方法时,是线程安全的。也可以理解为:

(1)它们的每个方法是原子的

(2)但注意它们多个方法的组合不是原子

4.1 不可变类线程安全性

String、Integer 等都是不可变类,因为其内部的状态不可以改变,因此它们的方法都是线程安全的。

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

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

相关文章

git@github.com: Permission denied (publickey).

本地虚拟机ubuntu上安装git&#xff0c;想从github上拉取项目到ubuntu上的过程。 1、在ubuntu上安装git 更新apt指令 sudo apt update 安装git sudo apt install git 查看安装git版本 git --version 2、ssh认证 首先已经安装了ssh指令 先执行 ssh -T gitgithub.com 执行之…

3.11 怎么增加小红书评论区的互动?【玩赚小红书】

今天就为大家总结了一下&#xff0c;关于小红书粉丝互动的一些小技巧&#xff0c;来供大家参考。 ​ ​ 一、 固好“真爱粉” 经常会在笔记下面评论、点赞、浏览笔记内容的粉丝&#xff0c;也就是所谓的“真爱粉”、“铁粉”&#xff0c;我们就需要用心维护这一部分粉丝。 ​…

虹科分享|硬件加密U盘|居家办公的网络安全:远程员工可以采取的步骤

新冠肺炎的流行迫使数以百万计的人在家工作&#xff0c;而当时他们对这一概念知之甚少&#xff0c;甚至完全没有经验。虽然许多员工已经重返办公室&#xff0c;但最近的一项研究发现&#xff0c;72%的受访者希望每周至少有两天在家工作&#xff0c;32%的人表示他们希望永久在家…

全波形反演的深度学习方法: 第 4 章 基于正演的 FWI (草稿)

本章论述经典的 FWI, 它基于正演方法. 本贴仅供内部培训. 4.1 FWI 问题 图 4.1 FWI 的输入与输出 [1].图 4.2 FWI 的数学式子.正演问题是建立从速度模型到地震数据的映射. 一般认为是单解的, 即一个速度模型只能生成一个地震数据 (如果不考虑噪声).反演问题是建立从地震数据到…

【题解】E. Sending a Sequence Over the Network(1741)

链接&#xff1a;https://codeforces.com/problemset/problem/1741/E 题目大意 给出一个数组&#xff0c;判断它是否是合法的&#xff0c;如果合法则输出YES&#xff0c;不合法则输出NO。 合法规则&#xff1a;一段序列中&#xff0c;这个序列的第一个或者最后一个的数值&…

岩藻多糖-聚乙二醇-胆固醇Cholesterol-PEG-FucoidanFucoidan-Cholesterol 岩藻多糖-胆固醇

岩藻多糖-聚乙二醇-胆固醇Cholesterol-PEG-FucoidanFucoidan-Cholesterol 岩藻多糖-胆固醇 中文名称&#xff1a;岩藻多糖-胆固醇 英文名称&#xff1a;Fucoidan-Cholesterol 别称&#xff1a;胆固醇修饰岩藻多糖&#xff0c;胆固醇-岩藻多糖 外观:固体或粘性液体&#xff…

终于有人将TWI(串行通讯接口)给讲通了!

目录 TWI的特性 数据传输格式 时钟同步 数据仲裁 功能描述 总线接口单元 频率生成单元 地址匹配单元 控制单元 传输模式 主机发送模式 主机接收模式 从机发送模式 从机接收模式 TWI的特性 两线模式&#xff0c;简单快捷&#xff1b;支持主机模式和从机模式&#xff…

「科普」如何评价供应商的MES系统

MES综合性很强&#xff0c;涉及到多个业务领域、多种技术和多专业&#xff0c;如何写好最难的投标技术方案呢&#xff1f;简搭(jabdp)根据多年经验&#xff0c;为大家进行梳理和分解&#xff0c;帮助发愁的你写出好方案&#xff01; MES是一个综合性很强的系统&#xff1a; 生…

68 - 令人迷惑的写法

---- 整理自狄泰软件唐佐林老师课程 1. 写法一 下面的程序想要表达什么意思&#xff1f; 1.1 历史原因 早期的C直接复用class关键字来定义模板 但是泛型编程针对的不只是类类型 class关键字的复用使得代码出现二义性 1.2 typename诞生的直接诱因 自定义类类型内部的嵌套…

猿如意|手把手教你下载、安装和配置PyCharm社区版

手把手教你使用猿如意下载、安装和配置PyCharm社区版&#xff0c;希望能帮助到有需要的童鞋。 文章目录前言一、下载安装猿如意二、安装PyCharm社区版1.通过猿如意找到PyCharm下载位置2.安装PyCharm三、对PyCharm社区版进行简单设置1.设置PyCharm社区版为中文2.安装第三方Pytho…

数据同步,还看Canal

一个系统最重要的是数据&#xff0c;有时对于一个业务场景&#xff0c;不单单是把数据保存在数据库中&#xff0c;还需要同步保存在ES&#xff0c;Redis等等中。这时阿里开源组件Canal由此而生&#xff0c;它可以同步数据库中的增量数据保存到其它存储应用中。 一、介绍 canal…

航空专场 | 无人机设计仿真流程讲解与案例实操

一、CFD在无人机上的应用 1、静、动气动系数计算以上介绍的无人机的流动状态一般为中低雷诺数&#xff0c;不可压缩流动。这些计算一般用S-A模型或者KW-SST模型进行计算&#xff0c;能够获得不错的工程精度。静、动气动力系数主要用于无人机操纵性和稳定性的分析&#xff0c;评…

串口 COM口,并口 LPT口,RS232、RS485、CAN

RS232 和 RS485 的区别 工作模式&#xff1a;RS232 为全双工&#xff0c;RS485 为半双工。 传输方式&#xff1a;RS485和RS232只是物理协议的通信&#xff08;即接口标准&#xff09;&#xff0c;RS485是差分传输方式&#xff0c;RS232是单端传输方式&#xff0c;但通信程序没有…

RabbitMQ_五种模式

1.Simple("Hello World") 构成&#xff1a;生产者、消费者、消息队列 配置类 构造函数参数&#xff1a;name durable exclusive autoDelete 仅创建队列&#xff0c;不创建交换机&#xff0c;也不进行队列和交换机的绑定 注&#xff1a;配置类置于生产者端或消费者…

如何处理 Angular 单页面应用里的 a 标签,避免点击后重新加载整个应用

问题描述 客户已经实现了一些“free html”组件&#xff0c;它是 HTML 的标题和包装器&#xff0c;与 OCC 响应一起作为内容。 <div [innerHTML]"data?.content | safeHtml"></div>这个 HTML 里包含了 anchor element&#xff1a; <div class&quo…

Linux源码——目录作用

Linux Linux是啥&#xff0c;不用多说&#xff0c;其源码结构也非常清晰。有以下理解&#xff1a; arch 每个系列的CPU都有一个对应的文件夹&#xff0c;里面包含每种CPU具体的操作&#xff0c;单独具体粗来每种CPU独有的管理或者操作。其他的文件夹都是通用的操作。 arch (…

孤核函数-isolation kernel

1.孤立核 一看到核函数&#xff0c;我们第一时间想到的就是核函数通过升维或者降维的方式来计算数据之间的相似度。他在SVM和聚类算法中应用广泛。 我们就直入主题来看一下孤核函数的数学推导。 在d维的空间分布着n个点。数学表达式为. 如图&#xff1a;一共20个点分布在2维空间…

浅析linux内核网络协议栈--linux bridge

1 . 前言 本文是参考附录上的资料整理而成&#xff0c;以帮助读者更好的理解kernel中brdige 模块代码。 2. 网桥的原理 2.1 桥接的概念 简单来说&#xff0c;桥接就是把一台机器上的若干个网络接口“连接”起来。其结果是&#xff0c;其中一个网口收到的报文会被复制给其他…

深入了解BLE(Bluetooth 5.3)持续更新...

目录 1 BLE的优点和局限性 1.1 BLE与经典蓝牙的区别 1.2 局限性 1.2.1 数据吞吐量 1.2.2 范围 1.3 BLE优势及应用 1.4 BLE的角色 1.5 BLE的层次结构 1.5.1 物理层&#xff08;PHY&#xff09; 1.5.2 链路层 1.5.2.1 数据包格式 1.5.2.2 状态机 1.5.2.3 设备地址 …

PTA_1164 Good in C_模拟

PTA_1164 Good in C_模拟 1164 Good in C 分数 20 全屏浏览题目 切换布局 作者 陈越 单位 浙江大学 When your interviewer asks you to write "Hello World" using C, can you do as the following figure shows? Input Specification: Each input file conta…