JavaGuide(3)
一、项目背景与简介
JavaGuide由GitHub用户Snailclimb开发并维护,是一个全面而深入的Java学习资源库。它旨在为Java初学者和有经验的开发者提供一个系统的学习路径和丰富的资源,帮助他们系统地学习和巩固Java及相关技术知识。
二、项目内容与特点
- Java基础:详细解释了Java的基本概念、语法和核心类库,为初学者打下坚实的基础。
- 集合框架:深入分析了ArrayList、LinkedList、HashMap等常用集合类的源码和使用场景,帮助开发者更好地理解和应用这些集合类。
- 并发编程:涵盖了线程、锁、并发集合等高级并发编程知识,帮助开发者掌握Java并发编程的核心技术。
- JVM:详细介绍了Java虚拟机的内存模型、垃圾回收机制和类加载过程,让开发者对Java的运行环境有更深入的了解。
- 新特性:总结了从Java 8到最新版本的各个版本的新特性,帮助开发者紧跟Java技术的最新发展。
此外,JavaGuide还涉及了计算机网络、操作系统、数据结构与算法等计算机科学基础知识,为开发者提供了一个全面的技术栈学习平台。
JavaGuide的特点还包括:
- 全面性:覆盖了Java开发的各个方面,从基础到高级,从理论到实践,应有尽有。
- 实用性:项目中的内容都是经过精心挑选和整理的,旨在解决实际开发中的常见问题。同时,提供了大量的代码示例和面试题,帮助开发者更好地理解和应用知识。
- 更新及时:紧跟Java的最新发展,及时更新内容,确保信息的时效性和准确性。
- 社区支持:JavaGuide是一个开源项目,拥有活跃的社区支持。用户可以在社区中参与贡献、寻求帮助或分享经验。
三、如何学习与使用JavaGuide
- 下载与安装:可以从JavaGuide的官方网站或GitHub仓库下载源代码压缩包,或者通过git命令来clone仓库。下载完成后,进入JavaGuide项目的根目录。
- 构建与运行:确保系统已经安装了Maven等构建工具,然后执行相应的命令来构建并运行JavaGuide。例如,可以使用“mvn clean package java -jar target/JavaGuide-xxx.jar”命令来运行JavaGuide。
- 学习与进阶:无论是Java初学者还是有一定经验的开发者,都可以通过JavaGuide系统地学习和巩固Java及相关技术知识。可以按照JavaGuide的学习路径逐步深入,也可以根据自己的兴趣和需求选择特定的章节进行学习。
- 面试准备:JavaGuide中包含了大量的面试题和解析,非常适合正在准备Java相关职位面试的求职者。可以通过学习这些面试题和解析来提高自己的面试技巧和竞争力。
- 日常开发参考:JavaGuide中的源码分析和最佳实践部分可以作为日常开发中的参考资料。在遇到问题时,可以查阅JavaGuide中的相关内容来寻找解决方案或灵感。
乐观锁和悲观锁详解
如果将悲观锁(Pessimistic Lock)和乐观锁(PessimisticLock 或 OptimisticLock)对应到现实生活中来。悲观锁有点像是一位比较悲观(也可以说是未雨绸缪)的人,总是会假设最坏的情况,避免出现问题。乐观锁有点像是一位比较乐观的人,总是会假设最好的情况,在要出现问题之前快速解决问题。
什么是悲观锁?
悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。
像 Java 中synchronized
和ReentrantLock
等独占锁就是悲观锁思想的实现。
public void performSynchronisedTask() {synchronized (this) {// 需要同步的操作}
}private Lock lock = new ReentrantLock();
lock.lock();
try {// 需要同步的操作
} finally {lock.unlock();
}
高并发的场景下,激烈的锁竞争会造成线程阻塞,大量阻塞线程会导致系统的上下文切换,增加系统的性能开销。并且,悲观锁还可能会存在死锁问题(线程获得锁的顺序不当时),影响代码的正常运行。
什么是乐观锁?
乐观锁总是假设最好的情况,认为共享资源每次被访问的时候不会出现问题,线程可以不停地执行,无需加锁也无需等待,只是在提交修改的时候去验证对应的资源(也就是数据)是否被其它线程修改了(具体方法可以使用版本号机制或 CAS 算法)。
在 Java 中java.util.concurrent.atomic
包下面的原子变量类(比如AtomicInteger
、LongAdder
)就是使用了乐观锁的一种实现方式 CAS 实现的。
CAS 算法
CAS 的全称是 Compare And Swap(比较与交换) ,用于实现乐观锁,被广泛应用于各大框架中。CAS 的思想很简单,就是用一个预期值和要更新的变量值进行比较,两值相等才会进行更新。
CAS 是一个原子操作,底层依赖于一条 CPU 的原子指令。
原子操作 即最小不可拆分的操作,也就是说操作一旦开始,就不能被打断,直到操作完成。
CAS 涉及到三个操作数:
- V:要更新的变量值(Var)
- E:预期值(Expected)
- N:拟写入的新值(New)
当且仅当 V 的值等于 E 时,CAS 通过原子方式用新值 N 来更新 V 的值。如果不等,说明已经有其它线程更新了 V,则当前线程放弃更新。
举一个简单的例子:线程 A 要修改变量 i 的值为 6,i 原值为 1(V = 1,E=1,N=6,假设不存在 ABA 问题)。
- i 与 1 进行比较,如果相等, 则说明没被其他线程修改,可以被设置为 6 。
- i 与 1 进行比较,如果不相等,则说明被其他线程修改,当前线程放弃更新,CAS 操作失败。
当多个线程同时使用 CAS 操作一个变量时,只有一个会胜出,并成功更新,其余均会失败,但失败的线程并不会被挂起,仅是被告知失败,并且允许再次尝试,当然也允许失败的线程放弃操作。
关于 CAS 的进一步介绍,可以阅读读者写的这篇文章:CAS 详解,其中详细提到了 Java 中 CAS 的实现以及 CAS 存在的一些问题。
一、JMM的基本概念
JMM定义了线程之间共享变量的可见性和有序性规则,为开发者提供了一种可靠的同步机制,以避免并发程序中常见的线程安全问题。JMM包含两个主要的内存区域:主内存和工作内存。
- 主内存:主内存是所有线程共享的内存区域,包含了程序的全局变量和静态变量。主内存是多个线程之间的交互媒介,线程之间通过主内存进行数据的传递和共享。
- 工作内存:工作内存是线程私有的内存区域,包含了线程栈中的局部变量和操作线程栈的操作数栈等。每个线程都有自己独立的工作内存,工作内存存储了线程在执行过程中需要用到的数据。
二、JMM的三大特性
JMM的三大特性是原子性、可见性和有序性,它们共同保证了多线程环境下数据的安全性和一致性。
-
原子性(Atomicity):
- 原子性指的是一个操作要么全部执行成功,要么全部不执行。JMM保证了对基本类型的读写操作的原子性。例如,对一个int类型的变量进行++操作,JMM保证这个操作不会出现读取脏数据或者写入不完整数据的情况。
- JMM通过使用synchronized关键字、volatile关键字和原子类(如AtomicInteger)等机制来保证原子性。
-
可见性(Visibility):
- 可见性指的是一个线程对一个变量的写操作对其他线程可见。即使在不同的线程中,一个线程对共享变量的修改也能被其他线程立即观察到。
- JMM通过使用锁机制和内存屏障来实现可见性。例如,使用synchronized关键字对代码块进行同步,每次进入同步块的线程都会从主内存中读取最新的值,保证了可见性。volatile关键字也可以确保被修饰的变量的写操作对其他线程立即可见。
-
有序性(Ordering):
- 有序性指的是在一个线程中的操作顺序与程序代码的顺序一致。然而,在多线程环境下,由于指令重排和缓存一致性等原因,程序的执行顺序可能与代码顺序不一致。
- JMM通过使用内存屏障来禁止特定类型的指令重排,保证程序的有序性。例如,volatile关键字可以禁止对volatile变量的读/写操作进行指令重排序。
三、JMM的Happens-Before规则
Happens-Before规则是JMM的核心原则之一,用于定义操作之间的顺序关系,基于此关系来保证数据的可见性和一致性。以下是Java中的Happens-Before规则:
- 程序顺序规则:在一个线程内,代码的执行顺序按照程序代码的书写顺序。
- 监视器锁规则:一个unlock操作在后续对同一锁的lock操作之前。
- volatile变量规则:对一个volatile变量的写操作先行发生于后面对该volatile变量的读操作。
- 线程启动规则:Thread.start()方法先行发生于此线程的每一个动作。
- 线程中断规则:对线程的interrupt()调用先行发生于被中断线程的代码检测到中断事件。
- 线程终止规则:线程的所有操作先行发生于此线程的终止检测(Thread.join()返回,Thread.isAlive()返回false)。
- 对象终结规则:对象的构造函数执行结束先行发生于finalize()方法的开始。
四、JMM的应用与注意事项
- 正确使用volatile关键字:当某个变量在多线程环境下被频繁读取且不需要复杂的同步操作时,可以使用volatile关键字来保证变量的可见性和有序性。
- 合理选择synchronized和Lock:在需要对共享资源进行原子操作且需要控制访问顺序时,可以使用synchronized关键字或Lock接口来保证原子性和可见性。
- 注意指令重排序的影响:编译器和处理器可能会对指令进行重排序以提高性能,但在多线程环境下,指令重排序可能导致内存可见性问题。因此,在编写多线程程序时,需要特别注意指令重排序的影响,并合理使用内存屏障等机制来保证程序的正确性。
相关文章:

JavaGuide(3)
一、项目背景与简介 JavaGuide由GitHub用户Snailclimb开发并维护,是一个全面而深入的Java学习资源库。它旨在为Java初学者和有经验的开发者提供一个系统的学习路径和丰富的资源,帮助他们系统地学习和巩固Java及相关技术知识。 二、项目内容与特点 Jav…...

微信小程序15天
UniApp(Vue3组合式API)和微信小程序15天学习计划 第1天:开发环境配置和基础知识 UniApp和微信小程序概述及对比安装并配置HBuilderX(UniApp)和微信开发者工具创建第一个UniApp Vue3项目和微信小程序项目了解两个平台的项目结构差异配置外部浏览器和各种小程序模拟…...

用Python制作数据可视化仪表盘:使用Dash与Plotly构建实时交互式仪表盘
解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在数据驱动的世界中,可视化是理解和解释复杂数据的关键工具。通过数据可视化,用户能够快速洞察数据趋势,做出明智决策。而仪表盘作为一种高度集成的可视化工具,能够将多种数据图表汇总到一个界面上,便于实时…...

干部管理系统:全面提升干部管理效能
数字化浪潮下,干部管理系统作为管理利器,日益凸显其核心价值。该系统全面实现干部信息的数据化,涵盖从基础档案到教育、工作、培训及考核等全方位细节,信息详尽且条理清晰。这不仅极大提升了干部信息查询与更新的效率,…...

Java之方法
方法(函数) Java中的方法必须定义在类或接口中。 package day2;import java.util.Scanner;public class way {public static void main(String[] args) {int arr[] new int[5];Scanner sc new Scanner(System.in);for (int i 0; i < arr.length;…...

MyBatis 数据表与实体映射的隐藏陷阱
这两天在处理一个线上问题时,发现Mybatis数据表和实体映射的时候会埋一个坑。这个问题看似微小,但却可能在关键时刻给我们带来不小的困扰。接下来,让我们深入剖析这个问题,并探究其发生的根源。 一、问题描述 我们在使用 Mybati…...

leetcode-239. 滑动窗口最大值
题目描述 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1: 输入:nums [1,3,-1,-3,5,3,6,…...

springboot项目中开启mybatis的sql日志
在 application.yml 文件中 添加 mybatis-plus 配置,再重启项目,这里用到了mybatis-plus的自带sql日志打印 # application-jdbc.yml mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl如果只是用的mybatis的话&#x…...

卷积的计算——nn.Conv2d(Torch.nn里的Convolution Layers模块里的Conv2d类)
**前置知识: 1、张量和通道 张量:多维数组,用来表示数据(图像、视频等) 通道:图像数据的一部分,表示不同的颜色或特征层 通道只是张量的其中一个维度 以一张RGB图像为例, 该图像…...

确保接口安全:六大方案有效解决幂等性问题
文章目录 六大方案解决接口幂等问题什么是接口幂等?天然幂等不做幂等会怎么样? 解决方案1)insert前先select2)使用唯一索引3)去重表加悲观锁4)加乐观锁之版本号机制5)使用 Redisson 分布式锁6&a…...

代码随想录算法训练营第二十九天| 93. 复原 IP 地址,78. 子集, 90. 子集 II
93. 复原 IP 地址,78. 子集, 90. 子集 II 93. 复原 IP 地址78. 子集90. 子集 II 93. 复原 IP 地址 有效 IP 地址 正好由四个整数(每个整数位于 0 0 0 到 255 255 255之间组成,且不能含有前导 0 0 0),整…...

【WebGis开发 - Cesium】三维可视化项目教程---初始化场景
系列文章目录 【WebGis开发 - Cesium】三维可视化项目教程—图层管理基础【WebGis开发 - Cesium】三维可视化项目教程—视点管理 目录 系列文章目录引言一、Cesium引入项目1.1 下载资源1.2 项目引入Cesium 二、初始化地球2.1 创建基础文件2.1.1 创建Cesium工具方法文件2.1.2 创…...

点云中ICP算法的详解
ICP(Iterative Closest Point)算法是一种用于刚性点云配准的经典算法。其核心思想是通过迭代地寻找两个点云之间的最近点对,并计算最优的刚性变换(包括旋转和平移),使得源点云在目标点云的坐标系下对齐。IC…...

抽象类Abstart Class
抽象类其实就是一种不完全的设计图 必须用abstract修饰 模板方法:建议使用final修饰,不能被重写。...

Redis:通用命令 数据类型
Redis:通用命令 & 数据类型 通用命令SETGETKEYSEXISTSDELEXPIRETTLTYPEFLUSHALL 数据类型 Redis的客户端提供了很多命令用于操控Redis,在Redis中,key的类型都是字符串,而value有多种类型,每种类型都有自己的操作命…...

【Python高级编程】探索Python库:创建引人入胜的交互界面
1.制作交互界面常用到的库 在 Python 中,有多个库可以用于创建交互界面(GUI)。 以下是一些常用的 Python GUI 库: Tkinter: Python 的标准 GUI 库,通常随 Python 一起安装。简单易用,适合快速开发小型应用…...

OpenCV Canny()函数
OpenCV Canny()函数被用来检测图像物体的边缘。其算法原理如下: 高斯滤波:使用高斯滤波器平滑图像以减少噪声。高斯滤波器是一种线性滤波器,可以消除图像中的高频噪声,同时保留边缘信息。计算梯度强度和方向:使用Sobe…...

Java基础(3)
基本数据类型 Java 中的几种基本数据类型了解么? Java 中有 8 种基本数据类型,分别为: 6 种数字类型: 4 种整数型:byte、short、int、long2 种浮点型:float、double1 种字符类型:char1 种布尔…...

【C语言】VS调试技巧
文章目录 什么是bug什么是调试(debug)debug和releaseVS调试快捷键监视和内存观察编程常见错误归类 什么是bug bug本意是“昆虫”或“虫子”,现在一般是指在电脑系统或程序中,隐藏着的一些未被发现的缺陷或问题,简称程…...

【华为HCIP实战课程七】OSPF邻居关系排错MTU问题,网络工程师
一、MTU MUT默认1500,最大传输单元,一致性检测 [R3-GigabitEthernet0/0/1]mtu 1503//更改R3的MTU为1503 查看R3和SW1之间的OSPF邻居关系正常: 默认华为设备没有开启MTU一致性检测! [R3-GigabitEthernet0/0/1]ospf mtu-enable //手动开启MTU检测 [SW1-Vlanif30]ospf mtu…...

速盾:休闲类游戏如何选择高防cdn?
休闲类游戏的流行度日益增长,越来越多的玩家在业余时间里选择放松自己,享受游戏带来的乐趣。然而,在休闲类游戏中,网络延迟和游戏载入速度的问题常常会影响到玩家的游戏体验。为了解决这些问题,选择一个高防CDN&#x…...

电脑插上U盘不显示怎么回事?怎么解决?
平时使用电脑的时候经常会使用U盘来传输数据或是备份文件,有时候会遇到一个令头疼的问题,比如,将U盘插入电脑的USB口后,设备却显示不出来。电脑上插入U盘后却不显示会影响我们的正常工作。接下来,我们一起分析一下故障…...

Python 如何使用 SQLAlchemy 进行复杂查询
Python 如何使用 SQLAlchemy 进行复杂查询 一、引言 SQLAlchemy 是 Python 生态系统中非常流行的数据库处理库,它提供了一种高效、简洁的方式与数据库进行交互。SQLAlchemy 是一个功能强大的数据库工具,支持结构化查询语言(SQL)…...

nginx主配置文件
Nginx的主配置文件nginx.conf,一般定义了Nginx的基本设置和全局配置。下面是对这个配置文件的详细解释: 文件结构 #user nobody; worker_processes 1;#error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log …...

使用数据库:
数据库: 1.为何需要数据库? 存储数据方法 第一种:用大脑记住数据, 第二种:写纸上, 第三种:写在计算机的内存中, 第四种:写出磁盘文件 2.数据库能做什么࿱…...

python list, tuple dict,set的区别 以及**kwargs 的基本用法
在python中, list, tuple, dict, set有什么区别, 主要应用在什么样的场景? 定义: list:链表,有序的项目, 通过索引进行查找,使用方括号”[]”; tuple:元组,元组将多样的对象集合到一起,不能修改,通过索引进行查找, 使用括号”()”; dict:字典,字典是一组键(key)和值(value…...

实用生活英语口语学习成人零基础入门柯桥专业外语培训
“秋裤”的英语表达 首先,秋裤肯定不是autumn pants,chill cool就更离谱了! 最地道的美语说法一定会用到“thermal”这个单词: ▼ “thermal”的意思是“热的、保温的”,由此延伸出“秋裤、保暖内衣”的表达ÿ…...

FLINK SQL数据类型
Flink SQL支持非常完善的数据类型,以满足不同的数据处理需求。以下是对Flink SQL数据类型的详细归纳: 一、原子数据类型 字符串类型 CHAR、CHAR(n):定长字符串,n代表字符的定长,取值范围为[1, 2147483647]。如果不指…...

汇编语言教程:打造你的第一款汇编语言小游戏 汇编语言教程攻略
目录 游戏详细简介 完整代码示例(不少于70行) 如何自学汇编语言游戏开发攻略及功能 游戏详细简介 游戏名称:“太空探险” 游戏简介:这是一款基于x86汇编语言开发的简单2D游戏。在游戏中,玩家扮演一名宇航员&#…...

白色简洁大方公司企业网站源码 WordPress主题2款
WordPress白色简洁大方公司企业网站主题2款 白色整洁风格wordpress主题是一款比较新颖的国际设计范风格 简洁而大方的 WordPress 主题,适合个人博客、企业和工作室用。 完美支持下拉菜单的wordpress企业主题。 wordpress简白企业模板是一款适合企业站以及工作室…...