学习目标:
面试进大厂
一个月时间掌握 Java 所有面试技巧
1.volatile是什么?:
1.是java虚拟机提供的轻量级的同步机制,符合JMM规范的2个特性,线程不安全,因为不保证原子性1.1 保证可见性
1.2不保证原子性
1.3禁止指令重排 保证有序性
如何保证原子性呢?
可以用atomicInteger来实现原子性
那什么是可见性?
首先要了解JMM(java 内存模型), 它是定义程序各个变量的访问方式的规范。
主内存:可以理解为自己电脑上内存条的内存
自己工作内存:每个线程去主内存拷贝一份到自己线程上的内存。
所以你们想想多个线程去操作主内存数据到自己工作内存,那修改数据成功后另一个线程如何知道数据被修改呢?所以jmm有一个可见性规范。
可见性:一个线程修改了,主内存通知所有线程
原子性:完整性,要么全部成功要么全部失败!
什么是指令重排?
有序性:多线程编译器会对指令进行优化重排,导致变量无法确定,结果无法预测,所以有序性可以禁止重排
单例模式在多线程可能存在哪些问题?:
单例模式分懒汉和饿汉式,只有懒汉式才线程不安全,因为他懒,每次创建对象前,都去判断一下是否为null,为null我才创建对象,不然就懒得创建。 但当线程同时进入判断时,就产生获取多个getInstance() 错误,可以用双端检索机制来解决,但可能会出现指令重排,因为在多线程环境下,底层为了优化有指令重排。public class SingletonDemo {
private static SingletonDemo instance = null;
private SingletonDemo() {
System.out.println(Thread.currentThread().getName() + "\t 我是构造方法SingletonDemo");
}
//DCL (Double Check Lock 双端捡锁机制)
public static SingletonDemo getInstance() {
if (instance == null) {
synchronized (SingletonDemo.class) {
if (instance == null) {
instance = new SingletonDemo();
}
}
}
return instance;
}
public static void main(String[] args) {
//并发多线程后,情况发生了很大的变化
for (int i = 1; i <= 20; i++) {
new Thread(() -> {
SingletonDemo.getInstance();
}, String.valueOf(i)).start();
}
}
}
就是先运行了return 所以还需要在instance属性上加volatile
private static volatile SingletonDemo instance = null;
cas介绍一下:
compare and swap 比较与交换
当一个值被自己线程内存修改时,提交给主内存时,会判断主内存的值是否被修改过 修改过则失败,反之则提前成功。
为什么他能包证原子性?
因为cas是一条cpu的原子指令,用了jre下rt.jar下sun.misc.UnSafe类 里面都通过native方法来访问本地底层系统,偏硬件 ,不会造成数据不一致
底层:
atomicInteger.getAndIncrement()方法里面调用了unsafe.getAndAddInt(),这个方法里面有一个do循环,利用compareAndSwapInt判断值是否和期望值相同,相同这退出,不同则一直循环!
csa的缺点?
1.由于csa底层是循环,所以开销大
2.只能对一个变量保证原子性
3.ABA问题 当2个线程同时访问时 一个线程速度较快,先对这个线程进行了修改,然后又修改回原来的值 ,此时就会产生ABA问题
如何解决ABA?
atomicStampedReference类给数据添加版本号
ArrayList安全吗?如何解决?
ArrayList默认容量10 自动扩容1.5倍
多线程下会报错 java.util.concurrentModificationException
可以用vector()来保证线程安全
我不给你用vector
那我用Collections.synchronizedList()解决
我不给你用Collections工具类
那我只能new一个juc下的CopyOnWriteArrayList()了
里面用到了volatile和Rentranlock
HashSet安全吗?如何解决?
底层hashMap
多线程下会报错 java.util.concurrentModificationException
1那我用Collections.synchronizedset()解决
2new一个juc下的CopyOnWriteArraySet()了
HashMap安全吗?如何解决?
多线程下会报错 java.util.concurrentModificationException
1 用concurentHashMap()
2用Collections.synchronizedMap()解决
3new一个juc下的CopyOnWriteArrayMap()了
公平和非公平锁
公平锁:线程按照顺序来获取锁,先来后到,排队
非公平锁:会出现线程加塞,就是插队获取锁,插入失败变为公平锁
可重入锁(递归锁)
线程可以进入任何一个已经拥有同步锁的里面的方法
简单说就是进入第一个方法锁后,第一个方法锁里还有另一个锁,该线程可以直接进入,可以避免死锁。
自旋锁
每个线程在进入锁时并不阻塞,而是在锁外循环,不进入等待区
独占锁和共享锁
独占锁:该锁只能被一个线程获取 是写锁
共享锁:可以被多个线程共享 是读锁
synchronized和Reentranlock区别
synchronized:是基于jvm的关键字底层是通过monitorenter和monitorexit对象来完成的,自动释放锁,不可中断,非公平,要么一个要么所有
lock是具体类是api层面的 手动释放锁unlock,可中断,公平非公平可以传true false切换 默认非公平,可以精确唤醒线程
## 生成一个适合你的列表
- 项目
- 项目
- 项目
1. 项目1
2. 项目2
3. 项目3
- [ ] 计划任务
- [x] 完成任务
## 创建一个表格
一个简单的表格是这么创建的:
项目 | Value
-------- | -----
电脑 | $1600
手机 | $12
导管 | $1
### 设定内容居中、居左、居右
使用`:---------:`居中
使用`:----------`居左
使用`----------:`居右
| 第一列 | 第二列 | 第三列 |
|:-----------:| -------------:|:-------------|
| 第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
### SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
| TYPE |ASCII |HTML
|----------------|-------------------------------|-----------------------------|
|Single backticks|`'Isn't this fun?'` |'Isn't this fun?' |
|Quotes |`"Isn't this fun?"` |"Isn't this fun?" |
|Dashes |`-- is en-dash, --- is em-dash`|-- is en-dash, --- is em-dash|
## 创建一个自定义列表
Markdown
: Text-to-HTML conversion tool
Authors
: John
: Luke
## 如何创建一个注脚
一个具有注脚的文本。[^2]
[^2]: 注脚的解释
## 注释也是必不可少的
Markdown将文本转换为 HTML。
*[HTML]: 超文本标记语言
## KaTeX数学公式
您可以使用渲染LaTeX数学表达式 [KaTeX](https://khan.github.io/KaTeX/):
Gamma公式展示 $\Gamma(n) = (n-1)!\quad\forall
n\in\mathbb N$ 是通过欧拉积分
$$
\Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,.
$$
> 你可以找到更多关于的信息 **LaTeX** 数学表达式[here][1].
## 新的甘特图功能,丰富你的文章
```mermaid
gantt
dateFormat YYYY-MM-DD
title Adding GANTT diagram functionality to mermaid
section 现有任务
已完成 :done, des1, 2014-01-06,2014-01-08
进行中 :active, des2, 2014-01-09, 3d
计划一 : des3, after des2, 5d
计划二 : des4, after des3, 5d
- 关于 甘特图 语法,参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:
这将产生一个流程图。:
- 关于 Mermaid 语法,参考 这儿,
FLowchart流程图
我们依旧会支持flowchart的流程图:
- 关于 Flowchart流程图 语法,参考 这儿.
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。