多线程一定比单线程快吗?
不一定,因为多线程存在上下文的切换工作,所以多线程不一定就比单线程快。
如何减少上下文切换
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接口