java多线程面试大全

学习目标:

面试进大厂
一个月时间掌握 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的流程图:

Created with Raphaël 2.2.0 开始 我的操作 确认? 结束 yes no
  • 关于 Flowchart流程图 语法,参考 这儿.

导出与导入

导出

如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

导入

如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值