Java多线程——synchronized、volatile 保障可见性

在这里插入图片描述

目录

  • 引出
  • synchronized、volatile 保障可见性
  • Redis冲冲冲——缓存三兄弟:缓存击穿、穿透、雪崩
    • 缓存击穿
    • 缓存穿透
    • 缓存雪崩
  • 总结

引出

Java多线程——synchronized、volatile 保障可见性


synchronized、volatile 保障可见性

  • 原子性:在一次或者多次操作时,要么所有操作都被执行,要么所有操作都不执行。
  • 可见性:当一个线程对共享变量进行修改后,另外一个线程可以立即看到该变量修改后的最新值。
  • 有序性:程序执行的顺序按照代码的先后顺序执行。

synchronized关键字和Lock相关的工具类可以保证原子性、可见性和有序性,volatile关键字可以保证可见性和有序性,不能保证原子性。

可见性:synchronize、volatile

原子性:synchronize

volatile保证数据的可见性,但是不保证原子性(多线程进行写操作,不保证线程安全);而synchronized是一种排他(互斥)的机制。

主线程无法感知t1线程修改了flag值:

private static Boolean flag = false;
public static void main(String[] args) throws Exception {Thread t1 = new Thread(()->{try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}flag = true;});t1.start();while (true) {if (flag) {System.out.println("线程修改了flag");break;}}
}

解决1:synchronized。 程序执行synchronized后,会清空工作内存副本数据,之后就从新从主内存获取数据

while (true) {synchronized (flag) { if (flag) {System.out.println("线程修改了flag");break;}}
}

某一个线程进入synchronized代码块前后,执行过程入如下:
线程获得锁
清空工作内存
从主内存拷贝共享变量最新的值到工作内存成为副本
执行代码
将修改后的副本的值刷新回主内存中
线程释放锁

解决2:volatile 也可以保证多线程之间访问共享变量时的可见性。

public class App10 {private static volatile Boolean flag = false;public static void main(String[] args) throws Exception {Thread t1 = new Thread(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}flag = true;});t1.start();while (true) {if (flag) {System.out.println("线程修改了flag");break;}}}
}

子线程t从主内存读取到数据放入其对应的工作内存
将flag的值更改为true,但是这个时候flag的值还没有写会主内存
此时main方法main方法读取到了flag的值为false
当子线程t将flag的值写回去后,失效其他线程对此变量副本
再次对flag进行操作的时候线程会从主内存读取最新的值,放入到工作内存中

总结: volatile保证不同线程对共享变量操作的可见性,也就是说一个线程修改了volatile修饰的变量,当修改写回主内存时,另外一个线程立即看到最新的值。

Redis冲冲冲——缓存三兄弟:缓存击穿、穿透、雪崩

缓存击穿

缓存击穿:redis中没有,但是数据库有

顺序:先查缓存,判断缓存是否存在;如果缓存存在,直接返回数据;如果缓存不存在,則查询数据库,将数据库的数据存入到缓存

在这里插入图片描述

解决方案:将热点数据设置过期时间长一点;针对数据库的热点访问方法上分布式锁;

缓存穿透

缓存穿透:redis中没有,数据库也没有

在这里插入图片描述

解决方案:

(1)将不存在的key,在redis设置值为null;

(2)使用布隆过滤器;

原理:https://zhuanlan.zhihu.com/p/616911933

在这里插入图片描述

布隆过滤器:

如果确认key不存在于redis中,那么就一定不存在;

它说key存在,就有可能存在,也可能不存在! (误差)

在这里插入图片描述

布隆过滤器

1、根据配置类中的 key的数量 ,误差率,计算位图数组【二维数组】

2、通过布隆过滤器存放key的时候,会计算出需要多少个hash函数,由hash函数算出多少个位图位置需要设定为1

3、查询时,根据对应的hash函数,判断对应的位置值是否都为1;如果有位置为0,则表示key一定不存在于该redis服务器中;如果全部位置都为1,则表示key可能存在于redis服务器中;

缓存雪崩

缓存雪崩:

Redis的缓存雪崩是指当Redis中大量缓存数据同时失效或者被清空时,大量的请求会直接打到数据库上,导致数据库瞬时压力过大,甚至宕机的情况。

造成缓存雪崩的原因主要有两个:

1.相同的过期时间:当Redis中大量的缓存数据设置相同的过期时间时,这些数据很可能会在同一时间点同时失效,导致大量请求直接打到数据库上。

2.缓存集中失效:当服务器重启、网络故障等因素导致Redis服务不可用,且缓存数据没有自动进行容错处理,当服务恢复时大量的数据同时被重新加载到缓存中,也会导致大量请求直接打到数据库上。

预防缓存雪崩的方法主要有以下几种:

1.设置不同的过期时间:可以将缓存数据的过期时间分散开,避免大量缓存数据在同一时间点失效。

2.使用加锁:可以将所有请求都先进行加锁操作,当某个请求去查询数据库时,如果还没有加载到缓存中,则只让单个线程去执行加载操作,其他线程等待该线程完成后再次进行判断,避免瞬间都去访问数据库从而引起雪崩。

3.提前加载预热:在系统低峰期,可以提前将部分热点数据加载到缓存中,这样可以避免在高峰期缓存数据失效时全部打到数据库上。

4.使用多级缓存:可以在Redis缓存之上再使用一层缓存,例如本地缓存等,当Redis缓存失效时,还能够从本地缓存中获取数据,避免直接打到数据库上。

在这里插入图片描述

本地缓存:ehcache oscache spring自带缓存 持久层框架的缓存


总结

Java多线程——synchronized、volatile 保障可见性

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

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

相关文章

Node.js---使用Express写接口

1. 创建基本的服务器 2. 创建 API 路由模块 // aoiRouter.js 路由模块 const express require(express) const apiRouter express.Router()module.exports apiRouter// ------------------------------------------// app.js 导入并注册路由模块 const apiRouter require(…

【C++】Unordered_map Unordered_set

在C98中,STL提供了底层为红黑树结构的一系列关联式容器,例如map、set等。它们在搜索数据时效率可达到O(logN),但最糟糕的情况下搜索需要比较红黑树的高度次,若此时树中的节点非常之多,那么搜索效率就非常不理想。 最理…

python绘制趋势线

趋势线 趋势线是用来显示数据趋势或者预测未来发展方向的一种图形表示方法。在统计学和数据分析中,趋势线通常是通过拟合数据点来找到一条最符合数据整体趋势的直线、曲线或者其他形状。常见的趋势线拟合方法包括线性回归、多项式回归、指数平滑等。 趋势线在金融…

OpenHarmony教程指南—Ability的启动模式

介绍 本示例展示了在一个Stage模型中,实现standard、singleton、specified多种模式场景。 本实例参考开发指南 。 本实例需要使用aa工具 查看应用Ability 模式信息。 效果预览 使用说明 1、standard模式: 1)进入首页,点击番茄…

贪心算法详解及机器人运动应用Demo

一、引言 贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。贪心算法在有最优子结构的问题中尤为有效。今天,我们将通过一个机器人运动的Demo来详细解析贪心算…

文心一言眼中的ChatGPT是什么样的

Q: 你好文心一言,请说一说你眼中的chatgpt A: 在我眼中,ChatGPT是一种非常先进和强大的自然语言处理模型,它展示了人工智能技术的显著进步。ChatGPT拥有出色的语言理解和生成能力,能够与用户进行流畅、自然的对话,并尝…

[c/c++] const

const 和 #define 的区别 ? const 和指针一块出现的时候,到底谁不能修改 ? const 和 volatile 能同时修饰一个变量吗 ? const 在 c 中的作用 ? 1 const 和 #define 的区别 const 和 #define 的相同点: (1) 常数 const 和 #define 定…

lanqiao:合根植物

题目描述: 代码实现:

私域商业模式创新:消费增值引领企业业绩飙升

大家好,我是吴军,专注于私域商业模式的深度探索。今天,我要分享的是一个极具启发性的客户故事。这家企业,在短短一个月内,业绩飙升至上百万级别,用户活跃度同样瞩目,日均在线用户稳定在八万至十…

关键信息标红

效果&#xff1a; 导入一个文本文件到textEdit中&#xff0c;对指定的key关键字标红处理或者对关键字所在的行进行整行标红处理 实现&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_EN…

Django-聚合查询

Django 使用聚合查询前要先从 django.db.models 引入 Avg、Max、Min、Count、Sum&#xff08;首字母大写&#xff09;。 from django.db.models import Avg,Max,Min,Count,Sum # 引入函数 res models.Book.objects.aggregate(Avg("price")) print(res, type(res…

华为数通学习笔记(一):数据通信网络基础

华为数通学习笔记 前言&#xff1a;在学习大数据的过程中&#xff0c;我发现很多地方需要用到网络知识点&#xff0c;由于我哥考取了华为数通 HCIE 证书&#xff0c;目前正在一家大公司担任技术负责人&#xff0c;因此借此机会我要向他学习这方面的知识点&#xff0c;希望能够拓…

dbeaver更换下载驱动地址

DBeaver 是一个免费开源的数据库工具&#xff0c;提供对多种数据库系统的支持&#xff0c;包括 MySQL、PostgreSQL、Oracle、SQLite 等。它是一个通用的数据库管理工具&#xff0c;可以帮助用户连接、管理和查询各种类型的数据库。 下载地址 使用dbeaver连接数据库时需要先下…

【Spring Boot 3】获取已注入的Bean

【Spring Boot 3】获取已注入的Bean 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花费或…

leetcode —— 多数元素

1 多数元素 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&#xff…

Linux:kubernetes(k8s)探针LivenessProbe的使用(9)

他做的事情就是当我检测的一个东西他不在规定的时间内存在的话&#xff0c;我就让他重启&#xff0c;这个检测的目标可以是文件或者端口等 我这个是在上一章的基础之上继续操作&#xff0c;我会保留startupProbe探针让后看一下他俩的执行优先的一个效果 Linux&#xff1a;kuber…

prometheus监控zookeeper方案

这里要求zookeeper版本必须达到3.6或以上&#xff0c;用的是官方自带的监控信息。 官方下载地址 https://zookeeper.apache.org/releases.html#download 然后在zookeeper的配置文件&#xff0c;比如zoo.cfg最后面加上这一段 metricsProvider.classNameorg.apache.zookeeper.…

洛谷P2233 公交车路线

本题题号特殊&#xff0c;相对简单。 题目描述 在长沙城新建的环城公路上一共有 88 个公交站&#xff0c;分别为 A、B、C、D、E、F、G、H。公共汽车只能够在相邻的两个公交站之间运行&#xff0c;因此你从某一个公交站到另外一个公交站往往要换几次车&#xff0c;例如从公交站…

【C++从0到王者】第五十站:B树

文章目录 一、内查找与外查找1.内查找2.外查找 二、B树概念三、B树的插入1.B树的插入分析2.B树插入总结3.插入代码实现4.B树满树和最空时候的对比5.B树的删除6.遍历B树7.B树的性能分析 一、内查找与外查找 1.内查找 像我们之前所用的在内存中的查找就是内查找 种类数据格式时…

logrotate日志轮转

logrotate配置文件&#xff1a; 主配置文件&#xff1a; /etc/logrotate.conf (决定每个日志文件如何轮转) 配置日志轮转 vim /etc/logrotate.conf weekly #轮转的周期 rotate 4 #保留4份 create #轮转后创建新文件 …