1、基础
2、线程和进程:
1.线程六个状态:
还有一个"终止"
2.wait和sleep的区别:
3、Lock锁(重点)
传统 Synchronized:
不公平锁
Lock接口:
公平锁:十分公平:可以先来后到非公平锁:十分不公平:可以插队 (默认)
Synchronized 和 Lock 区别:
1、 Synchronized 内置的Java关键字, Lock 是一个Java类
2、 Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁
3、 Synchronized 会自动释放锁,lock 必须要手动释放锁!如果不释放锁,死锁
4、 Synchronized 线程 1(获得锁,阻塞)、线程2(等待,傻傻的等);Lock锁就不一定会等待下去;
5、 Synchronized 可重入锁,不可以中断的,非公平;Lock ,可重入锁,可以 判断锁,非公平(可以自己设置);
6、 Synchronized 适合锁少量的代码同步问题,Lock 适合锁大量的同步代码!
4、生产者和消费者问题
面试的:单例模式、排序算法、生产者和消费者、死锁
生产者和消费者问题 Synchronized 版
解决if用While
5.lock与Synchronized对应的方法:
Synchronized:
(重):
- 多个线程用同一个对像,调用同一个类被Synchronized锁的方法,变量,线程都只能一个一个来调用!
-
多个线程如果用的是不同对像(不同的类),调用被Synchronized锁的方法,变量,线程不相干扰!
static修饰的概念是类的模板,任何类还没加载就要先加载类它的模板,类的模板只有一个。
如果被static(静态修饰),就算用不同的对象(名字)声明,static修饰的都是指向它唯一的类模板,只能一个一个调用!
6、Condition的使用
lockd等待,唤醒方法:
condition1.signal();唤醒condition1
Lock-精准唤醒:
7、List的安全
List<String> list = new CopyOnwriteArrayList<>();
8、Set的安全
Set<string> set = new CopyOnwriteArrayset<>();
9、map的安全
Collections.synchronizedMap(Map<K,V> m) )可以代替HashMap,但是它们都是通过使用一个全局的锁来同步不同线程间的并发访问,因此会带来不可忽视的性能问题。
Map<string, string> map = new ConcurrentHashMap<>();
ConcurrentHashMap是J.U.C(java.util.concurrent包)的重要成员,它是HashMap的一个线程安全的、支持高效并发的版本。在默认理想状态下,ConcurrentHashMap可以支持16个线程执行并发写操作及任意数量线程的读操作。本文将结合Java内存模型,分析JDK源代码,探索ConcurrentHashMap高并发的具体实现机制,包括其在JDK中的定义和结构、并发存取、重哈希和跨段操作,并着重剖析了ConcurrentHashMap读操作不需要加锁和分段锁机制的内在奥秘和原理。
11、常用辅助类
CountDownLatch
线程减法计数器
CyclicBarrier
线程加法计数器
Semaphore
12、读写锁
使用
没有加锁时:
结果
读锁和写锁
又名(独占锁和共享锁)
结果
总结
13、阻塞队列
队列和阻塞
BlockingQueue
总
1、抛出异常:
2、返回Boolean值
3、一直阻塞
4、超时等待
14、同步队列
SynchronousQueue
BlockingQueue<String> blockingQueue = new SynchronousQueue<>(); //同步队列
结果:
总结
15、线程池
Executors线程池
Executors线程池三大方法
1、单个线程池
2、固定线程池
3、可伸缩线程池
三大方法本质
ThreadPoolExecutor
1、阿里巴巴规范手册说明
2、ThreadPoolExecutor七大参数
2、ThreadPoolExecutor四种拒接策略
1、
2、
3、
4、
池大小设置优化
1、CPU密集型
2、IO密集型
16、四大函数式接口
1、Function函数式接口
还能把括号去掉
2、断定型接口
3、Consumer消费型接口
4、 Supplier供给型接口
17、Stream流式计算(1.8新特性)
18、ForkJoin
1、ForkJoin的特点:工作窃取
双端队列
2、使用和对比
使用三种方法计算1+到10亿的值
1、普通For循环
2、ForkJoin
2.1、编写计算类
2.2、创建ForkJoin工厂执行计算
3、Stream流式计算
一行代码
4、结果
19、异步回调
CompletableFuture
1、没有返回值()
2、有返回结果(supplyAsync)
20、JMM
JMM的八种指令
21、Volatile
1、保持可见性
缓存锁:
总线加锁
缓存一致性协议
2、不保证原子性
如:多线程调用num++;
除了加锁lock和synchronized还有原子类可以保证原子性
原子类CAS
实现
3、避免指令重排
Volatile的实现
(2)禁止指令重排底层原理:
volatile实现禁止指令重排优化,从而避免多线程环境下程序出现乱序执行的现象。
先了解下概念,内存屏障(Memory Barrier)又称内存栅栏,是一个CPU指令,它的作用有两个:
保证特定操作执行的顺序性;
保证某些变量的内存可见性(利用该特性实现volatile内存可见性)
volatile实现禁止指令重排优化底层原理:
由于编译器和处理器都能执行指令重排优化。如果在指令间插入一条Memory Barrier则会告诉编译器和CPU,不管什么指令都不能和这条Memory Barrier指令重排,也就是说通过插入内存屏障,就能禁止在内存屏障前后的指令执行重排优化。内存屏障另外一个作用就是强制刷出各种CPU的缓存数据,因此任何CPU上的线程都能读取到这些数据的最新版本。
左边:写操作场景:先LoadStore指令,后LoadLoad指令。
右边:读操作场景:先LoadLoad指令,后LoadStore指令。
22、单例模式
概念:
java中单例模式是一种常见的设计模式,单例模式的写法有很多种,比较常见的有三种:懒汉式、饿汉式、内部类、双重验证。
单例模式有以下特点:
1、单例类只能有一个实例(new 的对象)。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式确保该类只被是实例化一次,并且只能自己实例化自己。
若想某一类不在类外被实例化,只需用private修饰符修饰其构造函数。
1、饿汉式
2、懒汉式
3、静态内部类式
23、深入理解CAS
AtomicInteger
1、Unsafe类
ABA问题
通俗来讲就是你大爷还是你大爷,你大妈已经不是你大妈了^_^(他已经被动过了)
代码实现
解决办法
如果线程one操作不被中断,那么问题就解决了
- 将类变成原子类
- 操作过程添加版本号
即为下面的原子引用!
24、原子引用
AtomicStampedReference
但是Integer类型的范围是-128~127,超出范围会在堆里面新建一个对象并不会复用对象
你自己看一下源码compareAndSet源码,底层是用==进行判断
带版本号的原子类
它被人动过,版本号就不是原来的版本号了
25、各种锁的理解
1、公平锁和非公平锁
2、可重入锁
(递归锁)
可重入锁是指:某个线程已经获取了某个锁,那么他可以再次获取该锁而不陷入死锁
总结下:什么是 "可重入",可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。
3、自旋锁
4、死锁
解开死锁,避免死锁产生的条件就可以了
26、ThreadLocal的原理和使用场景
区别: