java知识随笔记

随笔记1

此博客是我在学习java中遇到的问题,我将这些零散的问题都记下了,主要是在我忘记的时候提醒我,所以好多知识点都很模糊,大家可以看看这些知识点自己是否会,不会可以去查询更专业详细的博客,我这里面可能存在大量问题,欢迎提出,我们一起进步

1.java 堆栈

栈是先进先出,,堆内存动态分布

栈内存储的是基本数据变量,以及引用变量(地址),变量在使用完毕后会被及时处理掉

堆内是 存储实际的数组元素,对象等,在使用完毕后,一段时间不使用,会被自动清理java知识随笔记java知识随笔记

2.事务的隔离级别

读未提交,会造成脏读,脏读是没有给修改添加锁,导致在修改中,读进来了,而修改未提交,读取数据错误

读已提交,会造成不可重复度,读已提交会给修改事务添加锁,是读无法插入到修改的事务中,但读没有添加锁,在两个读之间会被修改插入,导致两次读取不一致。

可重复读,会造成幻读,可重复读在读已提交的基础上给读加上了锁,修改操作无法插入,但是没有禁止插入操作,就会造成幻读问题

序列化:几乎是单线程,没有问题,效率低。

3.数组和链表

如果需要快速访问数据,很少或不插入和删除元素,就应该用数组;相反, 如果需要经常插入和删除元素就需要用链表数据结构了

4.锁的四种状态

从高到低依次为无状态锁,偏向锁,轻量级锁和重量级锁

无状态锁就是没有加锁

偏向锁:加锁” 实际上是将自身线程信息写入目标对象头信息中,并设置状态为“偏向锁状态”

​ “解锁” 实际上并没有做任何事

​ “尝试加锁” 实际上是检查目标对象头中的偏向锁拥有者是否是自己,如果是,那么说明没有其他线程修改,无需再次进行加锁操作

轻量级锁:自旋锁(cas)

重量级锁:悲观锁

5.jmm的三种特性

原子性:一个操作不能被打断,要么全部执行完毕,要么不执行。在这点上有点类似于事务操作,要么全部执行成功,要么回退到执行该操作之前的状态。

可见性:一个线程对共享变量做了修改之后,其他的线程立即能够看到(感知到)该变量的这种修改(变化)

有序性:对于一个线程的代码而言,我们总是以为代码的执行是从前往后的,依次执行的。这么说不能说完全不对,在单线程程序里,确实会这样执行;但是在多线程并发时,程序的执行就有可能出现乱序。用一句话可以总结为:在本线程内观察,操作都是有序的;如果在一个线程中观察另外一个线程,所有的操作都是无序的。前半句是指“线程内表现为串行语义(WithIn Thread As-if-Serial Semantics)”,后半句是指“指令重排”现象和“工作内存和主内存同步延迟”现象。

volatile关键字可以保证jmm的可见性和有序性,但不能保证原子性

6.乐观锁

乐观锁的实现方式,cas和版本号

cas是自旋锁,可以在不加悲观锁的情况下保证数据的正确性。

cas会导致aba问题。

7.java多线程上下文

CPU处理任务时不是一直只处理一个,而是通过给每个线程分配CPU时间片,时间片用完了就切换下一个线程。时间片非常短,一般只有几十毫秒,所以CPU通过不停地切换线程执行时我们几乎感觉不到任务的停滞,让我们感觉是多个线程同时执行。

CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再次加载这个任务的状态,从任务保存到再加载的过程就是一次上下文切换。

8.wait和sleep的区别

wait来自Object类

sleep来自Thread类

wait会释放锁

sleep不会释放锁

wait必须在同步代码块中

sleep可以在任何地方睡