Java知识:面向对象、锁升级、Hash容器、String区别、线程池

面向对象:

三大特性:
①封装:对象属性及实现对外隐藏,只提供公共访问方式,提高复用性和安全性。
②继承:继承是多态前提,提高代码复用性。
③多态:父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,提高了程序拓展性。

五大基本原则:
①单一职责原则:类的功能要单一
②开放封闭原则:模块对于扩展是开放的,对于修改是封闭的。
③里式替换原则:子类可以替换父类出现在父类能出现的地方。
④依赖倒置原则:高层次模块不应依赖于低层次模块,都应该依赖于抽象;抽象不应依赖于具体实现,具体实现应依赖于抽象。
⑤接口分离原则:设计时采用多个与有关接口比用一个通用接口好。

锁:

在Java中,锁是位于对象头上的标记。

Synchronized:
保证原子性。
①修饰代码块:在代码块开始位置插入monitor entry指令,结束插入monitor exit指令,当对象的monitor被持有,将处于锁定状态。
②修饰方法:不再通过插入指令实现,而是方法调用来获取运行时常量池中ACC_SYNCHRONIZED标志实现,若该标记被设置,当方法执行前获取对象的monitor对象,若成功执行结束,释放monitor,若monitor被其他线程获取,线程阻塞。

volatile:
可保证有序性、可见性,不能保证原子性。
①防止指令重排序
②保证变量可见性:原本取数值,线程需要在CPU开辟缓存区,用于快速获取数据,但当一个线程在缓存区更改了数值,没有写入CPU,另一个线程在CPU又取该数,两者值就发生偏差。使用volatile后,取数据直接从CPU读取,保证变量可见性。

锁升级:
①无锁:没有加锁,所有线程可访问。
②偏向锁:因为一个加锁资源可能大多情况被某个线程占有,此时就可以将该线程ID记录,当线程访问结束不会释放锁。有线程访问资源时,若是记录的线程,则继续访问。所以偏向锁在没有其他线程参与竞争时,锁一直被常用线程持有。
③自旋锁:在偏向锁基础上,一旦有线程竞争资源,偏向锁会升级为自旋锁。竞争的两个线程都会在栈帧中生成锁记录空间,用于存储锁对象当前记录的拷贝,用CAS才做将记录设置为指向自己线程的锁记录的指针,至此获得锁。其他若未获得锁,会一直自旋(不用进入阻塞态)等待,直到竞争成功。
CAS:更新的原子操作,当前值与传入值一样则更新,否则失败。
④重量级锁:为了避免长时间资源消耗资源,JVM在自旋超过10次后(或CPU核数一半),升级到重量锁。该锁依赖于操作系统的mutex互斥锁,也就是将线程调度交给操作系统(线程阻塞),减少了CPU消耗,但会使程序相应速度变慢。

Hash组件:

HashMap和HashTable区别:
①线程:HashMap非线程安全,HashTable线程安全(用synchronize实现)。
②效率:因线程修饰,HashMap效率优于HashTable
③对null:HashMap可以存储一个null的key和多个null的值;HashTable不允许key和值为null
④初始容量、扩容:HashMap初始16,扩容2n(当数组内容数量大于阈值<数组长度*负载因子>就会扩容);HashTable初始11,扩容让2n+1
⑤底层:当HashMap底层数组长度大于64,链表大于8,链表将转换为红黑树,减少搜索时间

补充:
HashMap长度2的幂次方:因为数组下标计算是(n-1)&hash,数组长度取2的幂次方,则(n-1)表现为二进制时,后面全是1,这时进行&操作,就实现高位清0,低位保留,这样可以将位置控制在数组内了。
处理hash冲突:hash获取对应数组下标,若发生冲突,在数据挂链表,当链表到一定长度转为红黑树

ConcurrentHashMap:
效率比HashTable高,并发性比HashMap好。
1.7->1.8:
分段锁 升级为 CAS+synchronized实现
链表存储 升级为 链表+红黑树

String:

在Java中字符串属于对象,当每次String操作,都会生成新的String对象,这样不仅效率低,也浪费空间。
如:

String str = "hello";  //开辟hello堆空间
str + "world";   //开辟world堆空间,开辟helloworld堆空间

上述操作开辟了三块空间。

String的==和equals():
String的==是用于内存中位置比较,如:直接拼凑位于字符串常量池,new是位于堆
equals()默认是首先进行地址比较,然后进行内容比较

StringBuffer、StringBuilder:
该两类对象能被多次修改且不产生新的未使用对象。
StringBuilder非线程安全,但效率高;StringBuffer线程安全。

线程池:

参数解释:

public ThreadPoolExecutor(int corePoolSize,
                      int maximumPoolSize,
                      long keepAliveTime,
                      TimeUnit unit,
                      BlockingQueue<Runnable> workQueue,
                      ThreadFactory threadFactory,
                      RejectedExecutionHandler handler)

①corePoolSize:核心线程数(默认一直存活)
②manimumPoolSize:线程池最大线程数
③keepAliveTime:当线程数大于corePoolSize,没有新任务提交,核心线程外的线程不会立刻销毁,直到超过该时间才会回收销毁
④时间单位
⑤任务队列:新任务到达时,放到队列中
⑥创新线程使用
⑦饱和策略

流程:
提交任务后->判断核心线程是否满
没有满:创建线程执行任务
满:判断等待队列是否满

队列未满:加入队列等待
队列满:判断线程池是否满

线程池未满:创建非核心线程执行任务
线程池满:按饱和策略处理

饱和策略:
①抛出异常,拒绝新任务处理(默认)
②让提交任务的线程直接执行(数据处理顺序不定)
③不处理新任务,直接丢弃
④丢弃最早的未处理请求

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔幻音

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值