登录
首页 >  数据库 >  MySQL

基础和线程

来源:SegmentFault

时间:2023-01-22 21:13:47 300浏览 收藏

来到golang学习网的大家,相信都是编程学习爱好者,希望在这里学习数据库相关编程知识。下面本篇文章就来带大家聊聊《基础和线程》,介绍一下MySQL、Redis、Java,希望对大家的知识积累有所帮助,助力实战开发!

jvm类加载器及类加载顺序

加载器

1)BootstrapClassLoader(启动类加载器)
  负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,加载System.getProperty(“sun.boot.class.path”)所指定的路径或jar。
2)ExtensionClassLoader(标准扩展类加载器)
  负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包。载System.getProperty(“java.ext.dirs”)所指定的路径或jar。
3)AppClassLoader(系统类加载器)
  负责记载classpath中指定的jar包及目录中class
4)CustomClassLoader(自定义加载器)
  属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现

类加载器的顺序

1)加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。
2)在加载类时,每个类加载器会将加载任务上交给其父,如果其父找不到,再由自己去加载。

3)Bootstrap Loader(启动类加载器)是最顶级的类加载器了,其父加载器为null。

image.png

spi

spi能带来的好处:
不需要改动源码就可以实现扩展,解耦。
实现扩展对原来的代码几乎没有侵入性。
只需要添加配置就可以实现扩展,符合开闭原则。

关键信息:ServiceLoader可以获取扩展实现的类实例
写好接口及实现类;
在resources目录下新建META-INF/services目录,并且在这个目录下新建一个与上述接口的全限定名一致的文件,在这个文件中写入接口的实现类的全限定名:

image.png

image.png

https://www.cnblogs.com/jy107...

B+tree

二叉树、平衡二叉树
B树结构

B树

 B树特点:
 每个节点都存储了子节点的指针和本节点的键值及数据;
 精确查找ok,范围查找有较多的io操作,范围越大,性能越低;

B+树结构

B+tree

B+ 树特点
1.非叶子节点只存储键值信息。
2.所有叶子节点之间都有一个双向链指针。(提升插入操作效率)
3.数据记录都存放在叶子节点中。

sql优化

slow_query配置 查看慢sql日志
最左匹配
explain 执行计划

binlog主从同步延迟

硬件问题提升硬件
分库分表

  • 针对数据库方面的拆分主要是结合分库分表来实现,即对于分库,则根据业务内聚性,拆分为几个相对独立的子服务,各个子服务使用独立的数据库分开部署,则可以将写操作分散到各个数据库,各个数据库的复制流量相对较小,从而通过分而治之的方法来降低整体的延迟

    线程状态

    public enum State {
    NEW,
    RUNNABLE, //调用start
    BLOCKED, //未拿到锁
    WAITING,
    TIMED_WAITING,
    TERMINATED;
    }

    线程池**

    Java线程池类型

  • newFixedThreadPool
    定长线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程数量不再变化,当线程发生错误结束时,线程池会补充一个新的线程
  • newCachedThreadPool
    可缓存的线程池,如果线程池的容量超过了任务数,自动回收空闲线程,任务增加时可以自动添加新线程,线程池的容量不限制
  • newScheduledThreadPool
    定长线程池,可执行周期性的任务
  • newSingleThreadScheduledExecutor
    单线程可执行周期性任务的线程池
  • newWorkStealingPool
    任务窃取线程池,不保证执行顺序,适合任务耗时差异较大。

newSingleThreadExecutor
单线程的线程池,线程异常结束,会创建一个新的线程,能确保任务按提交顺序执行
Java线程池参数
corePoolSize 线程池核心线程大小
maximumPoolSize 线程池最大线程数量
keepAliveTime 空闲线程存活时间
Timeunit 空闲线程存活时间单位
workQueue 工作队列

①ArrayBlockingQueue
②LinkedBlockingQuene
③SynchronousQuene
④PriorityBlockingQueue

threadFactory 线程工厂
拒绝策略
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务
ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

jvm调参与内存问题排查

volatile

1.保证有序性
2.保证可见性
3.不保证原子性
场景:
1)对变量的写操作不依赖于当前值
2)该变量没有包含在具有其他变量的不变式中
保证对变量操作的原子性才可使用volatile

gc

回收哪些内存
可达性分析算法:每个对象都被对象的引用,root object
两种回收算法
标记删除法、标记整理法
内存模型 minor gc为年轻代区域回收 majorgc 为老年代区域回收

image.png

常见垃圾回收器CMS G1, jdk9后默认从CMS切换到G1
fullgc 触发条件

  • 调用System.gc
  • 老年代空间不足
  • 永久代空间不足

jvm内存模型

线程隔离:程序计数器(Program Counter Register)、虚拟机栈(VM Stack)、本地方法栈(Native Method Stack)
线程共享:堆(Heap)、方法区(Method Area)
堆内存是 JVM 内存中最大的一块内存空间,该内存被所有线程共享,几乎所有对象和数组都被分配到了堆内存中。
方法区主要是用来存放已被虚拟机加载的类相关信息,包括类信息、常量池(字符串常量池以及所有基本类型都有其相应的常量池)、运行时常量池
程序计数器记录各个线程执行的字节码的地址,例如,分支、循环、跳转、异常、线程恢复等都依赖于计数器
虚拟机栈是线程私有的内存空间,它和 Java 线程一起创建。
当创建一个线程时,会在虚拟机栈中申请一个线程栈,用来保存方法的局部变量、操作数栈、动态链接方法和返回地址等信息,并参与方法的调用和返回。
本地方法栈跟虚拟机栈的功能类似,虚拟机栈用于管理 Java 方法的调用,而本地方法栈则用于管理本地方法的调用。
但本地方法并不是用 Java 实现的,而是由 C 语言实现的。
每一个方法的调用都伴随着栈帧的入栈操作,方法的返回则是栈帧的出栈操作

countDownLatch

用于协调多个线程,待线程执行完之后再继续执行,即主线程等待多个子线程完成

单例

public class Singleton {  
 private volatile static Singleton instance = null;  
 private Singleton() {}  
 public static Singleton getInstance() {  
  if (instance == null) {  
   synchronized (Singleton.class) {// 1  
    if (instance == null) {// 2  
     instance = new Singleton();// 3  
    }  
   }  
  }  
  return instance;  
 }  
}

这里是主要是要理解为什么要使用volatile修饰变量才行,是因为:
volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作,所以才不会出现对象还在创建就被其他线程拿去使用的情况,其他线程都会得到一个创建好的对象
使用内部类实现延迟加载

public class Singleton {  
 private Singleton() {}  
 private static class Holder {  
 
  private static Singleton instance = new Singleton();  
 }  
 public static Singleton getInstance() {  
  // 外围类能直接访问内部类(不管是否是静态的)的私有变量  
  return Holder.instance;  
 }  
}

以上就是《基础和线程》的详细内容,更多关于mysql的资料请关注golang学习网公众号!

声明:本文转载于:SegmentFault 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>