java学习笔记(3)

jdk、jre、jvm
  • 从大到小的包含关系
==和equals区别
  • == 比较的时栈中的值,基本数据类型是变量值,引用类型则是堆中内存对象的地址
  • equals默认和==一样,会重写,string会重写,
  • string本身是final static的,每个对象==是不同的,但是equals就会返回true
final
  • 修饰类:不能被继承
  • 修饰方法:不能被子类覆盖
  • 修饰变量:不能更改值
    • 类变量,只能在静态初始代码块中赋值
    • 成员变量,可以在非静态初始化赋值,但是必须在引用之前赋值
    • 修饰局部变量,只能在局部函数或匿名类使用:因为保证局部函数运行时的正确性,实际访问的是局部变量的copy
    • 修饰基本类型不能更改,修饰引用变量不能修改引用,但是可以修改所引用的值 如final int[] a = {1,2,3,4} 可以修改a[1] = 3
string、stringbuffer、stringBuilder
  • string是final修饰的,每次操作产生新的string对象
  • stringBuffer和stringBuilder都是在原对象上操作
  • stringBuffer是线程安全,有synchronized修饰,而stringBuilder则不是线程安全
  • 性能stringbuilder>stringbuffer>string
重载和重写
  • 重载:发生在同一个类中,方法名不同,参数类型不同,个数不同,顺序不同都是重载,但是返回值不同不能当作重载,存在两个函数名参数相同,返回值不同会直接编译错误
  • 重写:发生在父类中,参数列表和方法名必须相同,返回值返回小于等于父类,抛出的异常小于等于父类,修饰符范围大于等于父类
抽象类和接口
  • 抽象类存在普通成员函数,接口只能存在public abstract()方法
  • 抽象类中的成员变量可以是各种类型的,接口中的成员变量只能是public static final类型的
  • 抽象类接口只能继承一个,接口可以实现多个
  • 接口是对行为的约束,抽象类是对共性的抽取
  • 抽象类关注类的本身共性,接口关注行为动作
  • 抽象类单继承,接口可以多继承
list和set
  • list:有序,可重复,内存连续存储,可以下标或者迭代取出
  • set:无序,不可重复,内存随机存储,只能迭代取出
hashCode和equals
  • 两个对象相等,hashcode一定相等,equals也相等
  • 相同的hashcode可能两个对象不一样(散列冲突)
  • hashcode的值是散列的下表,如果没有重写hashcode,不可能存在两个一样的hashcode
arraylist和linkedlist
  • arraylist:基于动态数组,内存连续,适合下表访问,尾部添加代价小,头部添加代价高
  • linkedlist:基于链表,可以分散存储于内存中,适合插入删除,不适合查询,查询需要遍历一遍
hashmap和hashtable
  • hashtable:线程安全
  • hashmap:数组加链表
    • 链表高度达到8,数组长度超过64,则转变为红黑树,小于6则重写变回链表
    • 计算key的hash值,然后二次hash对数组长度取模,对应到数组,没有产生冲突,直接存入。
    • 产生冲突equals比较,相同则取代,不同则插入链表
    • key为null,存储在下标为0的位置
    • 数组扩容和动态数组扩容一样
concurrenthashMap
  • 采用分段锁机制
  • synchronized+cas+node+红黑树,node和val都是用volatile修饰
    • volatile的作用是让并发时写操作强制在读操作前
  • 查找、替换。赋值都是用cas
  • 扩容使用synchronized
  • 第一次hash找到对应的segment,第二次hash找到对应的链表头
  • 对数据的扩容都是以segment为粒度,更加的细微,写入修改的加锁是对头节点。读取不加锁,但是有volatile机制
IOC
  1. 配置文件扫描路径
  2. 递归包扫描获取.class文件
  3. 反射、确定交给IOC管理的类
  4. 对需要注入的类进行依赖注入
java类加载器
  • booststrapClassloader:lib下的jar包和class文件
  • extClassloader:lib/ext包下的jar包和class类
  • appClassloader:自定义类加载器,负责加载classpath文件
双亲委派
  • 从下往上委派,从上往上查找缓存是否加载,找到之后就加载当前的类,所以同名类都是加载最高层

  • 从上往下加载:如果没找到,则从上往下加载,在哪个加载器找到就加载哪个加载器的class

  • 好处,安全,防止用户自己编写类覆盖核心源码

  • 避免重复加载

java中异常
  • 顶层throwable
  • execption和error
  • checkexection和runtimeException
gc如何判断对象可以回收
  • 引用数为0
  • 可达性分析
线程的声明周期
  • 创建、就绪、运行、阻塞、死亡
  • 等待阻塞,运行中的线程执行wait方法,线程会释放所有资源,jvm把线程放入等待池中,开始等待,不能自动唤醒,需要其他线程调用notify或者notifyall方法。
  • 同步阻塞,没有抢到锁,会放入锁池中
  • 其他阻塞,sleep方法或者join方法(在B线程中调用A.join则会在A执行之后再执行B)
  • 新建状态:新创建一个线程
  • 就绪状态:线程对象创建之后,调用start()方法,处于可运行线程池中等待cpu调度
  • 运行:cpu正在运行线程
  • 阻塞状态,放弃cpu使用权,暂停运行,知道就绪状态
  • 死亡:执行完成,结束生命周期
sleep/wait/join/yield
  • 锁池
    • 所有需要竞争同步锁的线程都会放在锁池中,得到锁后进入就绪态
  • 等待池
    • 待用wait()方法后,线程静入等待池,等待池线程不会竞争同步锁,只有调用notify才会被唤醒加入锁池竞争锁,notify是随机唤醒一个等待池,notifyall唤醒所有
  1. sleep是thread类方法,wait是object类的本地方法
  2. sleep不会释放锁,wai会释放锁
  3. sleep不依赖同步器syn,wait需要
  4. sleep不需要唤醒,wait需要
  5. sleep一般用于当前线程休眠或者循环暂停,wait主要用于多线程通信
  6. sleep会让出cpu执行时间强制上下文切换,wait不一定,wait之后有机会重新竞争到锁
  • yield执行后线程直接进入就绪状态,马上释放cpu执行权,但是依然保留了cpu的执行资格,可能下一个就会执行
  • join执行后线程a会等待线程b执行完或者中断
thread和runable
  • thread类,实现了runable
  • runable接口
守护线程
  • 为非守护线程提供服务的线程
  • 任意一个守护线程都是jvm中非守护线程的保姆
  • 不能拥有固定资源
  • 系统线程设置为守护线程也会被转成用户线程
ThreadLocal的原理
  • thread包含一个threadlocalmap类型的成员变量threadlocal存储本线程中所有threadloca对象及对应的值

  • 线程间相互独立,说明线程安全

  • 每个threadlocalMap里面存储entry对象,key是弱引用的threadlocal对象,值是线程变量。可由set、get操作

    1. 对象跨层传递时,可以避免多次传递,使用同一个threadlocalmap
    2. 线程间数据给力
    3. 事务操作,存储线程事务信息
    4. 数据库连接,Session会话管理
threadlocal内存泄漏及避免
  • 不再被使用的对象或者变量占用的内存不能被回收,就是内存泄漏会导致内存溢出
  • 强引用(new,反射),一个对象具有强引用,不会被垃圾回收器回收,如果想强制取消关联,可以显示应用赋值为null
  • 弱引用,总是被gc回收,常在缓存中使用
  • key是弱引用,被回收会存在值无法被回收的情况
  • 但是当被回收后调用THreadLoaclMap的set()get()remove()时,就会消除key为null的value值
  • 每次使用threadlocal都要调用remove()方法进行清楚数据
  • 将thread local定义成private static。这样就一直存在threadlocal的强引用,这样就能通过threadlocal的弱应用访问到entry的value值
并发三大特性
  • 原子性
  • 可见性
  • 有序性
线程池和线程池参数
  • 降低资源消耗,提高线程的利用率,降低创建和销毁的消耗
  • 提高响应度
  • 提高线程的可管理性
    • corepoolsize代表核心线程数,创建后一般不会消除
    • maxinumPoolSize代表最大线程数,与核心线程数对应
    • keepAliveTime,unit表示超出核心线程数之外的线程的空闲存活时间
    • workQueue用来存放待执行的任务
    • threadFactory线程工厂
    • handler任务拒绝策略,两种情况,调用shutdown等方法结束时,线程池内部有还没有执行完成的任务,但线程池关闭,所以会拒绝,还有就是到达最大线程数,无法处理新提交的任务
线程池流程
  1. 添加任务-
  2. 检查核心线程是否满 no 创建核心线程
  3. 任务队列是否满 no 添加到任务队列
  4. 最大线程是否达到 no 创建临时线程
  5. 拒绝策略
线程池阻塞队列
  • 达到最大队列后,可以通过阻塞保留需要入队的线程
    • 自带休眠唤醒
  • 创建新线程时,需要获取全局锁,其他线程都得阻塞
线程池复用
  • 每个线程都会重复执行任务,调用run方法。
  • 线程和任务分离,线程池不包含逻辑,run方法里面拥有逻辑
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值