我们都知道导致可见性的原因是缓存,导致有序性的原因是编译优化。那解决可见性和有序性的办法就是禁用缓存和禁用编译优化了,不过我们都知道缓存和编译优化的目的是为了提高 CPU 的效率从而提高程序的性能,所以不能完全禁止,折中的方案就是按需禁用缓存和编译优化。
那么,如何进行按需禁用呢?
对于这个问题,Java 提供了 Java 内存模型(JMM)这个方案来解决。
我们都知道导致可见性的原因是缓存,导致有序性的原因是编译优化。那解决可见性和有序性的办法就是禁用缓存和禁用编译优化了,不过我们都知道缓存和编译优化的目的是为了提高 CPU 的效率从而提高程序的性能,所以不能完全禁止,折中的方案就是按需禁用缓存和编译优化。
那么,如何进行按需禁用呢?
对于这个问题,Java 提供了 Java 内存模型(JMM)这个方案来解决。
乐观锁对应于生活中乐观的人总是想着事情往好的方向发展,悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。这两种人各有优缺点,不能不以场景而定说一种人好于另外一种人。
总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized
和ReentrantLock
等独占锁就是悲观锁思想的实现。
JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 java 语言的反射机制。
在讲JDK 代理和 CGLIB 代理前需要先了解代理模式。
代理模式是一种比较简单的设计模式。简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。
代理模式的主要作用是扩展目标对象的功能,比如说在目标对象的某个方法执行前后你可以增加一些自定义的操作。
代理分为静态代理和动态代理两种。
最近了解了下 Linux 性能相关的东西,主要是如何查看服务器性能的一些工具,在这里做个记录,以后遇到相关使用场景的时候,方便查看。
CPU利用率、用户时间(表示CPU在用户进程上的时间百分比)、系统时间(表示CPU花在内核操作上的时间百分比)、空闲时间、平均负载、阻塞、上下文切换、中断等
空闲内存、Swap利用率、缓冲和缓存、活动和非活动内存等
IO等待、平均队列长度、每秒传输(TPS)等
接收和发送的包、每秒碰撞(各个网络接口所连接网络的所发生的冲突数量)、丢包、错误等
AOP,面向切面编程。其实并不是什么很深奥的理论,就是当你想在做完某个操作后,希望在这个操作的发生前,发生后,返回值后等等场景里,进行一些相应的操作时,不需要每次都要重复的写一遍相应的操作,而是把这些操作定义成一个切面,通过定义好相应的切点后,在操作发生时,由框架帮你把你所定义好的切面织入进来,从而让你再开发的过程中,只需要聚焦于业务即可,而不用每次去处理很多重复的细节。
AOP 最典型的应用是在数据库事务的管控中。比如要保存用户时,需要连同用户的角色一并保存如数据库,此时,用 OOP 无法完成这样的事务操作,而 AOP 可以完成这些事情。
1 | public class Test<T> { |
1 |
|
需注意点:
1 | class MyTest<T> implements Test<T> { |
1 | class MyTest implements Test<String> { |