Java 并发编程的艺术中面试重点

多线程一定比单线程快吗?

不一定,因为多线程存在上下文的切换工作,所以多线程不一定就比单线程快。

 

如何减少上下文切换

1. 无锁并发: 将数据分段

2. CAS 算法, 原子操作底层是CAS

3.使用最小的线程数

4.使用协程

 

死锁

死锁是多线程编程中很重要的概念,线程t1和线程t2互相等待对方释放锁

写一段死锁的演示代码

 

避免死锁的方法

 

volatile 关键字

volatile 保证内存的可见性,不保证原子性,禁止指令重排。

简单分析volatile 的底层原理,将数据从线程缓存中拷贝回主内存。

 

synchronized 的实现和原理

java 中任意一个对象都可以作为锁,具体表现为以下三种形式:

1. 对于普通同步方法,锁住当前实例对象

2.对于静态同步方法,锁住当前类对象

3.对于同步方法快,锁住括号内的配置对象

 

当一个线程尝试访问同步代码块时,必须得到锁,退出或抛出异常时必须释放锁

 

锁的升级和优化

大多数情况下,锁不仅不存在多线程的竞争,而且总是由同一线程多次获得,为了让线程获得锁的代价更低,引入偏向锁,当一个进程获取锁时,会记录下来,在以后进入或退出的时候不需要进行CAS操作。

 原子操作, 底层为CAS操作

 

CAS 操作的问题

ABA问题

如果一个值开始是A,中间是B,最后又是A,CAS操作无法识别。

循环时间长,消耗CPU资源

只能保证一个共享变量的原子操作

Java 内存模型

 

懒汉式单例的双重检查锁对写法要加volatile,是因为读取到instance不为null的话,instance的对象可能没有初始化。

                                                                                                                                                                                                           

Java的线程有六种状态

NEW, RUNABLE,BLOCKED, WAITING, TIME_WAITING, TERMINATED     
 

线程间通信

volatile 和 synchronized

notify,notifyAll, wait

 

线程的等待通知范式、

等待方的伪代码

synchronized (对象) {
    while (条件不满足){
        对象.wait()
    }
    处理对应的逻辑
}

通知方的伪代码

synchronized (对象) {
    改变对象
    对象.notifyAll();
}

  Thread.join 方法

 

Java 中的Lock关键字

重入锁的概念         

公平锁和非公平锁

读写锁

Condition接口

                                                                                                                                                                                       

 

点赞