Concurrent Programming 2024-08-04 并发编程三要素 原子性 一个不可再被分割的颗粒,原子性指的是一个或多个操作要么全部执行成功要么全部执行失败 期间不能被中断,也不存在上下文切换,线程切换会带来原子性的问题。 有序性 程序执行的顺序按照代码的先后顺序执行,因为处理器可能会对指令进行重排序。 可见性 一个线程A对共享变量的修改,另一个线程B能够立刻看到 锁分类 悲观锁、乐观锁 悲观锁适合写操作多的场景 乐观锁适合读操作多的场景 乐观锁的吞吐量会比悲观锁多 悲观锁 当线程去操作数据的时候,总认为别的线程会去修改数据,所以它每次拿数据的时候都会上锁,别的线程去拿候就会阻塞,比如synchronized、ReentrantLock 乐观锁 每次去拿数据的时候都认为别人不会修改,更新的时候会判断别人是否回去更新数据 通过版本判断如果数据被修改了就拒绝更新,比如CAS是乐观锁,但严格来说并不是锁,通过原子性来保证数据的问步。 比如说数据库的乐观锁,通过版本控制来实现,乐观的认为在数据更新期间没有其他线程影响 公平锁、非公平锁 公平锁 指多个线程按照申请锁的顺序来获取锁,简单来说如果一个线程组里,能保证每个线程都能拿到锁。比如Reen....
JVM 2024-08-16 线程状态转换图 线程状态(State枚举值代表线程状态) 新建状态( NEW): 线程刚创建, 尚未启动。Thread thread = new Thread()。 可运行状态(RUNNABLE): 线程对象创建后,其他线程(比如 main 线程)调用了该对象的 start 方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取 cpu 的使用权。 运行(running): 线程获得 CPU 资源正在执行任务(run() 方法),此时除非此线程自动放弃 CPU 资源或者有优先级更高的线程进入,线程将一直运行到结束 阻塞状态(Blocked): 线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞 等待(WAITING): 进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。 超时等待(TIMED_WAITING): 该状态不同于WAITING,它可以在指定的时间后自行返回。 终止(TERMINATED): 表示该线程已经执行完毕,如果一个线程的run方法执行结束或者....
Annotation 2024-07-18 annotation 注解是在JDK5 时引入的新特性,其实就是代码里的特殊标记 注解也被称为元数据,是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用 允许开发人员在不改变源代码的情况下,在源代码中添加一些元数据 以便让编译器或者其他工具可以读取这些元数据,从而实现更高级的功能 应用场景 生成文档 编译时进行格式检查,如@Override 替代配置文件功能,比如spring的注解 和反射组合应用,自己封装框架组件 Java自带的标准注解 这些注解后编译器就会进行检查 @Override 标记覆写父类的方 @Deprecated 标记被修饰的类或类成员、类方法已废弃、过时 @SuppressWarnings 用于关闭对类、方法、成员编译时产生的特定警告, 元注解 用于定义注解的注解 元注解也是Java自带的标准注解,只不过用于修饰注解,比较特殊。 @Target:表示该注解用于什么地方 ElementType.CONSTRJCTOR 用在构造器 ElementType.FIELD 用于描述域-属性上 ElementType.METHOD 用在方法上 ElementTy....
Reflection 2024-07-18 Reflection java的反射(reflection)机制是指在程序的运行状态中 可以构造任意一个类的对象 可以了解任意一个类的成员变量和方法 可以了解任意一个对象所属的类 可以调用任意一个对象的属性和方法 这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制 反射核心:得到编译以后得class文件对象,提供了一个Class类型,就是编译后的class类对象 Base类 package com.soulboy.reflection; public class Base { private String job; public String getJob() { return job; } public void setJob(String job) { this.job = job; } } User类 package com.soulboy.reflection; public class User extends Base { private int age; public String name; public User() { } public User....
Generics 2024-07-16 什么是泛型(generics) 是在定义类、接口和方法时,可以在声明时通过一定的格式指定其参数类型 使用时再指定具体的类型,从而使得类、接口和方法可以被多种类型的数据所实例化或调用 这种可以在编译时进行参数类型检查的技术被称为泛型,是JDK5中引入的一个新特性 本质是参数化类型给类型指定一个参数,在使用时再指定此参数具体的值,那这个类型就可以在使用时决定 Generics的优点 把运行时的错误,提前到编译时,这样就可以在编译时把错误提示出来,避免了运行时出现错误 使用泛型可以提高代码的复用性,因为它可以支持多种类型的数据。 为什么要用泛型(generics) 在没有泛型之前,从集合中读取到的每一个对象都必须进行类型转换 如果插入了错误的类型对象,在运行时的转换处理就会出错 集合容器里面如果没指定类型默认都是Object类型,那什么到可以插入 减少了源代码中的强制类型转换,代码更加可读 作用域 泛型类 public class soulboy <泛型类型1,泛型类型2……> { …… } 泛型接口 interface soulboy <泛型类型1,泛型类型2……>....
Redis分布式锁同步问题-Redlock 2024-07-10 分布式锁知识回顾 业务场景 优惠券领券限制张数 商品库存超卖 …… 起因 为了防止分布式系统中的多个进程之间相互干扰,我们需要一种分布式协调技术来对这些进程进行调度 利用互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题 实现目标 保证同一时间只有一个客户端可以对共享资源进行操作。 解决方案 Redis+Lua脚本 使用Redission框架(底层也是Lua+WatchDog机制) Redis主从架构下的锁同步问题 生产环境下一般都是集群部署,则存在主从架构下的锁同步问题。 节点一在主节点获取分布式锁成功。 Redis主节点再同步数据到从节点时宕机,数据没同步成功。 高可用机制则Redis从节点升级为主节点(但是没有锁信息)。 节点二在新的Redis上也成功获取分布式锁。 导致一个锁资源同时被两个节点获取,这个就出现了问题。 Redlock算法 官方文档 Redis从3.0版本开始支持 Redlock算法,通过在多个 Redis 节点上创建同一个锁来防止主从节点之间出现的数据不一致的问题。 在 Redlock 算法中,需要从多个Redis节点获取锁,并对取锁结果进行校验,从而避免....
Vue3 2024-10-26 Node.js环境安装 Node版本选择 下载地址:https://nodejs.org/en/download Windows11安装Node.js参考步骤 切换镜像测试 # 切换镜像源 npm config set registry https://registry.npmmirror.com # 查看是否生效 npm config get registry # 进行安装测试 npm install -g express VScode(Visual Studio Code) 下载地址:https://code.visualstudio.com/Download Vue官网 快速上手 通过CDN使用Vue <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</t....