多线程 -- 线程安全问题(3)

本篇重点: 总结线程安全问题的原因以及解决办法

目录

    • synchronized 加锁关键字
        • join 和 synchronized 的区别
        • volatile 关键字

在上一篇中我们介绍了Thread类的基本使用方法, 本篇将会介绍有关于线程的安全问题

线程不安全的原因:

  1. 抢占式执行(罪魁祸首, 万恶之源)

  2. 多个线程修改同一个变量

    一个线程修改同一个变量 => 安全
    多个线程读取同一个变量 => 安全
    多个线程修改不同变量 => 安全
    
  3. 修改操作并不是原子的

    像是++操作就不是原子操作
    
  4. 内存可见性, 引起的线程不安全

  5. 指令重排序, 引起的线程不安全

线程不安全代码案例
使用两个线程来累加 count 的值, 每个线程循环 1w 次,累加变量 count 的值,count 默认值为 0,注意线程安全问题。

class Counter{
    private int count;
    public void add() {
            count++;
    }

    public int getCount() {
        return count;
    }
}
public class ThreadDemo13 {

    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();

        // 搞两个线程各自自增5w次看结果
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                counter.add();
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                counter.add();
            }
        });
        t1.start();
        t2.start();

        // 等待两个线程执行结束, 然后看结果
        t1.join();
        t2.join();
        System.out.println(counter.getCount());

    }
}

因为count++操作并不是原子性的所以线程并不安全

如何解决以上线程不安全问题???

synchronized 加锁关键字

加锁!!!

对count++ 进行加锁

此处使用代码块的方式来表示

进入synchronized 修饰的代码块的时候, 就会触发加锁 
出了synchronized 代码块, 就会触发解锁
    public void add() {
            synchronized (this){// this 指向的是count对象
                count++;
            }
    }

也可以在方法前加上synchronized关键字

    synchronized public void add() {
    	count++;
    }

join 和 synchronized 的区别

join只是让两个线程完整的进行串行
加锁, 两个线程的某个小部分串行了, 大部分都是并发的!!!

volatile 关键字

Volatile关键字的作用主要有如下两个:
1.线程的可见性:当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。
2. 顺序一致性:禁止指令重排序。

被volatile 优化的关键字,会禁止编译器进行优化
当循环次数下降了, load操作, 不再是负担了, 编译器就没必要优化了
指令重排序, 也是编译器优化的策略

public class ThreadDemo14 {
    volatile public static int flag = 0;

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            while (flag == 0) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("循环结束, t1线程结束");
        });
        Thread t2 = new Thread(() -> {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入一个整数: ");
            flag = scanner.nextInt();
        });
        t1.start();
        t2.start();
    }
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CTF入门指南

何为CTF &#xff1f; CTF&#xff08;Capture The Flag&#xff09;夺旗比赛&#xff0c;在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式。CTF起源于1996年DEFCON全球黑客大会&#xff0c;以代替之前黑客们通过互相发起真实攻击进行技术比拼的方式。…

《逆商》我们该如何应对坏事件

关于作者 作者保罗史托兹博士是逆商理论的提出者和奠基人&#xff0c;他曾被《人力资源》杂志评为 “全球十大有影响力的思想家”。在二十多年前提出逆商理论之后&#xff0c;他一直在致力于帮助各行各业的人士提高逆商&#xff0c;在实践中积累了该领域大量的数据和经验。 关…

二叉树的认识

愚昧将使你达不到任何成果&#xff0c;并在失望和忧郁之中自暴自弃。 --达芬奇 目录 &#x1f341;一.二叉树的概念 &#x1f341;二.二叉树的特点&#xff0c;结构 &#x1f341;三.三种特殊的二叉树 &#x1f341;1.斜树 &#x1f341;2.满二叉树 …

redis

1. 什么是Redis&#xff1f;它主要用来什么的&#xff1f; Redis&#xff0c;英文全称是Remote Dictionary Server&#xff08;远程字典服务&#xff09;&#xff0c;是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提…

基于计算机视觉的手势识别技术

一个不知名大学生&#xff0c;江湖人称菜狗 original author: Jacky Li Email : 3435673055qq.com Time of completion&#xff1a;2023.5.2 Last edited: 2023.5.2 手语是一种主要由听力困难或耳聋的人使用的交流方式。这种基于手势的语言可以让人们轻松地表达想法和想法&…

雷达中的无源和有源的区别

常规雷达探测目标时&#xff0c;需要源源不断地发射无线电波&#xff0c;所以叫有源雷达( active radar)。有源雷达的优点是能自主搜索目标&#xff0c;因为它接收的是自己发射的电磁波&#xff0c;所以灵敏度高&#xff0c;分辨率好。但这种雷达易受目标的电磁干扰&#xff0c…

C语言进阶——字符函数和字符串函数(下)

在前面我们已经学习了strlen、strcpy、strcat、strcmp几个库函数&#xff0c;今天我们继续学习剩余的库函数。 上期链接&#xff1a; C语言进阶——字符函数和字符串函数&#xff08;上&#xff09;_wangjiushun的博客-CSDN博客 目录&#xff1a; 3、长度受限制的字符串函数…

不愧是字节出来的,太厉害了...

前段时间公司缺人&#xff0c;也面了许多测试&#xff0c;一开始瞄准的就是中级水准&#xff0c;当然也没指望能来大牛&#xff0c;提供的薪资在15-20k这个范围&#xff0c;来面试的人有很多&#xff0c;但是平均水平真的让人很失望。看了简历很多上面都是写有4年工作经验&…

文件包含的本质、预处理符号、# vs ##

何为头文件&#xff1f; 在C语言中&#xff0c;文件包含是一种常见的编程技术&#xff0c;它允许程序员在一个源文件中使用另一个源文件中的函数或变量。 文件包含通常使用#include预处理指令来实现。#include指令告诉预处理器将文件的内容插入到当前文件的指定位置中。 例如&a…

python学习-基础知识总结

&#xff08;一&#xff09;基础语法 1.1、注释 程序添加注释&#xff0c;可以用来解释程序某些部分的作用和功能&#xff0c;提高程序的可读性&#xff0c;注释有两种形式&#xff1a; 单行注释&#xff1a;#多行注释&#xff1a;单引号&#xff08;注释内容&#xff09;或双…

笔试强训 Day6

选择题 1.十进制变量i的值为100&#xff0c;那么八进制的变量i的值为&#xff08;&#xff09; A 146 B 148C 144 D 142 本题很简单&#xff1a;100除8&#xff0c;取余数&#xff0c;直到商为零&#xff0c;最后反向的串起余数即可 2.执行下面语句后的输出为&#xff08;&…

【Python从入门到进阶】21、爬虫相关概念介绍

接上篇《20、HTML页面结构的介绍》 上一篇我们正式进入了Python爬虫的实战教程&#xff0c;主要讲解了要爬取的HTML页面的结构。本篇我们来介绍爬虫的相关概念。 一、什么是互联网爬虫 如果我们把互联网比作一张大的蜘蛛网&#xff0c;那一台计算机上的数据便是蜘蛛网上的一个…

unity制作一款塔防游戏

文章目录 介绍寻路系统怪物生成器制作3种初级炮台、3种升级炮台设置炮台属性选择炮台&#xff0c;添加监听事件炮弹追踪攻击敌人拖动鼠标实现相机视角转换鼠标光标放在cube上变色文字动画 介绍 关键技术&#xff1a; 寻路系统 生成怪物算法 粒子系统 line renderer制作追踪射线…

通过Python的pdfplumber库提取pdf中表格数据

文章目录 前言一、pdfplumber库是什么&#xff1f;二、安装pdfplumber库三、查看pdfplumber库版本四、提取pdf中表格数据1.引入库2.定义pdf文件路径3.打开pdf文件4.获取pdf文件中的页数5.遍历每一页6.获取当前页内容7.提取表格数据8.输出表格数据9.效果 总结 前言 大家好&#…

Scala学习(九)---List集合

文章目录 1.List1.1 不可变List集合1.2 可变集合ListBuffer 1.List List集合默认为不可变集合&#xff0c;List集合在实例化的时候&#xff0c;无法通过new关键字进行实例化&#xff0c;只能通过伴生apply方法来对其进行实例化 1.1 不可变List集合 创建一个不可变list集合 …

HUD(抬头显示)的方案介绍

目录 一、基于DLP3030-Q1的HUD电路设计 二、DLP3030-Q1的介绍 三、DLP3030-Q1工作原理 四、DLPC120-Q1DMD 显示控制器 五、TMS320F2802332 位 MCU 六、 HUD显示实例 HUD主板实例 七、HUD的软件环境 一、基于DLP3030-Q1的HUD电路设计 本设计采用了DLP3030-Q1 芯片组&…

设计模式 -第1部分 避免浪费- 第1章 Flyweight 模式 - 共享对象避免浪费

第1部分 避免浪费 注&#xff1a;其内容主要来自于【日】-结城浩 著《图解设计模式》20章节 极力推荐大家阅读原著 第1章 Flyweight 模式 - 共享对象避免浪费 1.1 Flyweight 模式 Flyweight 的意思"轻量级"&#xff0c;其在英文中的原意指比赛中选手体重最轻等级的一…

【C语言】实现猜数字游戏——随机数

&#x1f6a9;纸上得来终觉浅&#xff0c; 绝知此事要躬行。 &#x1f31f;主页&#xff1a;June-Frost &#x1f680;专栏&#xff1a;C语言 该篇将对 选择与循环语句 进行运用&#xff0c;实现猜数字游戏。 需求&#xff1a;游戏后可以选择再次进行游戏&#xff0c;也可以选择…

「实在RPA·烟草数字员工」助力烟草行业数字化转型加速度

烟草行业作为烟草产业链上重要一环&#xff0c;外部连接烟草工业企业、零售客户、消费者&#xff0c;内部包含营销、专卖、烟叶、物流等诸多业务&#xff0c;信息系统众多&#xff0c;企业数据量庞大。因此&#xff0c;清楚地了解自身存在的痛点&#xff0c;找到适合自身业务需…

如何在华为OD机试中获得满分?Java实现【寻找峰值】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…