自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(26)
  • 收藏
  • 关注

原创 Java并发编程 第七章 共享模型之不可变对象

定义 英文名称:Flyweight pattern. 当需要重用数量有限的同一类对象时出自 "Gang of Four" design patterns归类 Structual patterns。

2024-09-08 21:27:17 974

原创 Java并发编程 第六章 共享模型之无锁

1000个线程,每个取10元,共一万,没加锁毫无疑问并发运行出错。方法加锁后正常输出了。

2024-09-07 16:48:31 1278

原创 Java并发编程 第五章 共享模型之内存

本章重点讲解了 JMM 中的可见性 - 由 JVM 缓存优化引起有序性 - 由 JVM 指令重排序优化引起happens-before 规则原理方面CPU 指令并行volatile模式方面两阶段终止模式的 volatile 改进同步模式之 balking。

2024-09-07 11:31:31 1131

原创 Java并发线程 共享模型之管程 5

每个线程都有自己的一个 Parker 对象,由三部分组成 _counter , _cond 和 _mutex 打个比喻线程就像一个旅人,Parker 就像他随身携带的背包,条件变量就好比背包中的帐篷。很多教程中把饥饿定义为,一个线程由于优先级太低,始终得不到 CPU 调度执行,也不能够结束,饥饿的情况不易演示,讲读写锁时会涉及饥饿问题。如果这时线程还在运行,那么下次他调用 park 时,仅是消耗掉备用干粮,不需停留,继续前进,因为背包空间有限,多次调用 unpark 仅会补充一份备用干粮。

2024-09-04 17:09:13 1286

原创 java并发 共享模型之管程 4.

obj.wait() 让进入 object 监视器的线程到 waitSet 等待obj.notify() 在 object 上正在 waitSet 等待的线程中挑一个唤醒obj.notifyAll() 让 object 上正在 waitSet 等待的线程全部唤醒它们都是线程之间进行协作的手段,都属于 Object 对象的方法。必须获得此对象的锁,才能调用这几个方法try {因为没获取此对象的锁。如下就可以了log.debug("执行");

2024-09-04 10:57:31 1243

原创 java并发 第四章共享模型之管程 3 synchronized 原理

轻量级锁的使用场景:如果一个对象虽然有多线程要加锁,但加锁的时间是错开的(也就是没有竞争),那么可以使用轻量级锁来优化。轻量级锁对使用者是透明的,即语法仍然是 synchronized假设有两个方法同步块,利用同一个对象加锁1. 创建锁记录(Lock Record)对象,每个线程都的栈帧都会包含一个锁记录的结构,内部可以存储锁定对象的Mark Word。

2024-09-02 20:56:18 841

原创 Java并发 第四讲 共享模型之管程 2变量的线程安全分析

否,Spring不额外设置scope的话均为单例,不是线程安全的,可设置为环绕通知变成局部变量解决。sdf虽然是局部变量,但foo是抽象方法有可能将他的引用暴漏给外部,因为 foo这种方法的行为是不确定的,可能导致不安全的发生,被称之为外星方法。这里说它们是线程安全的是指,多个线程调用它们同一个实例的某个方法时,是线程安全的。i++虽然不是原子操作,但它是局部变量,不同的方法调用会在不同的栈帧里创建,不存在共享的问题,否,是,是,否,否,最后一个因为加了final只是地址不变,但地址指向的东西有可能变。

2024-09-02 19:22:29 663

原创 Java并发编程 第四章 共享模型之管程 上

先看一段代码结果有可能是0有可能是负数还有可能正数这是因为i++和i--并不是原子操作i++实际会产生如下的 JVM 字节码指令:单线程下这八条指令是顺序执行(不会交错)没有问题。但多线程下这 8 行代码可能交错运行出现负数的情况出现正数的情况一个程序运行多个线程本身是没有问题的,问题出在多个线程访问共享资源,多个线程读共享资源其实也没有问题,但在多个线程对共享资源读写操作时发生指令交错,就会出现问题。一段代码块内如果存在对共享资源的多线程读写操作,称这段代码块为临界区。

2024-08-30 21:00:29 1177

原创 Java并发编程之Java线程下

在一个线程 T1 中如何“优雅”终止线程 T2?这里的【优雅】指的是给 T2 一个料理后事的机会。1. 错误思路1.使用线程对象的 stop() 方法停止线程,stop 方法会真正杀死线程,如果这时线程锁住了共享资源,那么当它被杀死后就再也没有机会释放锁,其它线程将永远无法获取锁2. 使用 System.exit(int) 方法停止线程目的仅是停止一个线程,但这种做法会让整个程序都停止,杀鸡用牛刀。2. 正确思路 两阶段终止模式//重新设置打断标记。

2024-08-28 17:35:59 531

原创 Java并发编程之Java线程中

改为start后区别1.直接调用 run 是在主线程中执行了 run,没有启动新的线程2.使用 start 是启动新的线程,通过新的线程间接执行 run 中的代码start只能调用一次,run可以调用多次。

2024-08-28 16:58:28 372

原创 Java并发编程之Java线程 上

当 Context Switch 发生时,需要由操作系统保存当前线程的状态,并恢复另一个线程的状态,Java 中对应的概念就是程序计数器(Program Counter Register),它的作用是记住下一条 jvm 指令的执行地址,是线程私有的状态包括程序计数器、虚拟机栈中每个栈帧的信息,如局部变量、操作数栈、返回地址等。其实就是线程,每个线程启动后,虚拟机就会为其分配一块栈内存。方法1 是把线程和任务合并在了一起,方法2 是把线程和任务分开了。查看指定 Java 进程(PID)的所有线程状态。

2024-08-28 15:48:06 535

原创 Java并发编程 进程与线程

操作系统中有一个组件叫做任务调度器,将 cpu 的时间片(windows下时间片最小约为 15 毫秒)分给不同的程序使用,只是由于 cpu 在线程间(时间片很短)的切换非常快,人类感觉是 同时运行的。但如果是四核 cpu,各个核心分别使用线程 1 执行计算 1,线程 2 执行计算 2,线程 3 执行计算 3,那么 3 个线程是并行的,花费时间只取决于最长的那个线程运行的时间,即 11ms 最后加上汇总时间只会花费 12ms 注:需要在多核 cpu 才能提高效率,单核仍然时是轮流执行。

2024-08-28 15:02:14 1397

原创 Spring源码 第十八讲 静态通知调用

可见before已经转化为环绕通知,因为MethodBeforeAdviceInterceptor implements MethodInterceptor, 实现了环绕通知。after同理,最后一个就是环绕通知所以没转化。因为调用链过程中某些同志要用到调用链对象。1. proceed() 方法调用链中下一个环绕通知。2. 每个环绕通知内部继续调用 proceed()3. 调用到没有更多通知了, 就调用目标方法。模拟调用链过程, 是一个简单的递归过程。1. 统一转换为环绕通知。3. 模拟调用链过程。

2024-08-28 10:25:08 430

原创 Spring源码第十七讲 @Aspect 到 Advisor

Before 前置通知会被转换为下面原始的 AspectJMethodBeforeAdvice 形式, 该对象包含了如下信息。有【资格】的 Advisor 一部分是低级的, 可以由自己编写, 如本例 A17 中的 advisor3。有【资格】的 Advisor 另一部分是高级的, 由解析 @Aspect 后获得。它的调用时机通常在原始对象初始化后执行, 但碰到循环依赖会提前至依赖注入之前执行。第一个是Spring给所有代理添加的,第二个是Config里的低级切面。此时先生成Bean1的代理再初始化。

2024-08-27 20:27:30 570

原创 Spring源码第十六讲 切点匹配

先判断方法上是否加了注解,再判断类上是否加了注解,前三个分别输出true,false,true,比较简单,最后这个应该也输出true但输出了false因为MergedAnnotations.from(method);@Transactional底层并不是AspectJExpressionPointcut实现,因为@Transactional用法比较复杂,除了加在方法上还可以加在类上。输出两个matches,应该只匹配bar方法,所以应该false第二个true;3. @Transactional底层实现。

2024-08-26 19:55:13 264

原创 Spring 源码第十三讲 cglib 代理进阶

3. methodProxy.invokeSuper 也是不反射调用,它会正常(间接)调用代理对象的方法,可以省略目标对象。2. methodProxy.invoke 是不反射调用,它会正常(间接)调用目标对象的方法(Spring 采用)五个参数分别为目标类型、代理类型、方法参数及返回值的描述、增强功能方法名和原始功能方法名。1. method.invoke 是反射调用,必须调用到足够次数才会进行优化。总结:和 jdk 动态代理原理查不多。2. 调用目标时有所改进,见上面代码。

2024-08-21 15:19:28 142

原创 Spring 源码第十二讲 jdk 动态代理进阶

在方法内每次都会调用,其实调用一次就行,放到静态代码块中,3.调整了foo和bar抛异常的类型,按运行时异常和检查异常抛。将需要增强的功能在invoke中实现,代理类只需要调用代理目标的invoke方法就行。代理类此时不需要以来目标了,甚至都不需要知道目标的存在。但这么写功能增强和调用目标都写死了,应该写成抽象方法,用的时候提供抽象实现,有利于将来扩展。此时foo方法和bar方法都时void,若有返回值还需要改进。}接口加了一个bar方法,它在代理类掉的也是foo的输出。

2024-08-21 10:35:00 362

原创 Spring源码第十讲 AOP 实现之 agent 类加载

2. 运行时需要在 VM options 里加入 -javaagent:C:/Users/manyh/.m2/repository/org/aspectj/aspectjweaver/1.9.7/aspectjweaver-1.9.7.jar把其中 C:/Users/manyh/.m2/repository 改为你自己 maven 仓库起始地址。反编译出来可见没有添加.before语句,这是因为这种方法不是增强字节码而是在类加载阶段进行增强。可以由阿尔萨斯查看。

2024-08-20 20:57:52 304

原创 Spring源码第九讲 AOP实现之ajc编译器

2. 运行时需要在 VM options 里加入 -javaagent:C:/Users/manyh/.m2/repository/org/aspectj/aspectjweaver/1.9.7/aspectjweaver-1.9.7.jar,把其中 C:/Users/manyh/.m2/repository 改为你自己 maven 仓库起始地址。这说明AOP除了代理实现也能由ajc 编译器,代理通过方法重写实现,如果静态方法就无能为力,而ajc就可以,他能直接改.class文件。

2024-08-20 20:17:26 336

原创 Spring源码第八讲 Scope

注:打开不同的浏览器, 刷新 http://localhost:8080/test 即可查看效果如果 jdk > 8, 运行时请添加 --add-opens java.base/java.lang=ALL-UNNAMED即可。同一浏览器刷新 第一个变了后面两个没变因为每次刷新是不同的请求。而不同的浏览器Request和session不同但aplicition一样。总结:在当前版本的 Spring 和 Spring Boot 程序中,支持五种 Scope。

2024-08-19 20:16:40 586

原创 Spring源码第六讲 Aware接口

可见BeanNameAware 注入 bean 的名字实现了ApplicationContextAware 接口后注入了容器。先执行Aware接口再执行初始化总结:Aware 接口用于注入一些与容器相关信息, 例如a. BeanNameAware 注入 bean 的名字b. BeanFactoryAware 注入 BeanFactory 容器c. ApplicationContextAware 注入 ApplicationContext 容器。

2024-08-18 19:54:16 1036

原创 Spring源码第五讲 BeanFactory 后处理器

1. Spring 操作元数据的工具类 CachingMetadataReaderFactory2. 通过注解元数据(AnnotationMetadata)获取直接或间接标注的注解信息3. 通过类元数据(ClassMetadata)获取类名,AnnotationBeanNameGenerator 生成 bean 名4. 解析元数据是基于 ASM 技术。

2024-08-17 21:35:21 730

原创 Spring源码第四讲 Bean后处理器

1. @Autowired 等注解的解析属于 bean 生命周期阶段(依赖注入, 初始化)的扩展功能,这些扩展功能由 bean 后处理器来完成2. 每个后处理器各自增强什么功能* AutowiredAnnotationBeanPostProcessor 解析 @Autowired 与 @Value* CommonAnnotationBeanPostProcessor 解析 @Resource、@PostConstruct、@PreDestroy。

2024-08-16 21:35:04 613

原创 Spring源码第三讲 Bean生命周期

一个受 Spring 管理的 bean,生命周期主要阶段有创建:根据 bean 的构造方法或者工厂方法来创建 bean 实例对象依赖注入:根据 @Autowired,@Value 或其它一些手段,为 bean 的成员变量填充值、建立关系初始化:回调各种 Aware 接口,调用对象的各种初始化方法销毁:在容器关闭时,会销毁所有单例对象(即调用它们的销毁方法)prototype 对象也能够销毁,不过需要容器这边主动调用。

2024-08-16 10:00:00 513

原创 Springy源码第二讲

beanFactory 不会做的事1. 不会主动调用 BeanFactory 后处理器2. 不会主动添加 Bean 后处理器3. 不会主动初始化单例4. 不会解析beanFactory 还不会解析 ${ } 与 #{ }这对开发人员并不友好,还是用applicationcontext好若一个bean同时添加@Autowired,@Resource,添加比较器后按谁的优先级高先使用,数字越大优先级越低。设计的真垃圾。

2024-08-15 18:21:38 912

原创 Spring源码第一讲 容器接口

1.BeanFactory是ApplicationContext的父接口,是Spring的核心容器,主要的ApplicationContext实现都组合了它的功能。ApplicationContext 组合并扩展了 BeanFactory 的功能国际化、通配符方式获取一组 Resource 资源、整合 Environment 环境、事件发布与监听。但实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能, 都由它的实现类提供。事件发布与监听,实现组件之间的解耦。

2024-08-15 15:16:38 510

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除