java多线程与高并发思维导图
思维导图:https://www.processon.com/mindmap/5e9e98fd6376897466837d50
1.基本概念
创建线程的3种方式 | 实现Runnable接口 | ||
继承Thread类 | run方法执行多线程部分 | ||
实现Callable接口,线程池 | |||
cpu | yeild方法,让出一下cpu | ||
join,加入线程。A jion B,等B执行完再执行A | |||
sleep,让给别的线程执行 | |||
线程的6种状态 | new | 新建状态,还没有调用start() | |
Runnable | Ready-就绪状态 | 等待cpu运行 | |
Running-运行状态 | 在cpu中运行 | ||
调用start(),交给操作系统,由线程调度器执行 | |||
TimeWaiting | Thread.sleep(time),o.wait(time),t.join(time),lockSupport.parkNanos(),lockSupport.parkUntil() | ||
时间结束 | |||
Waiting | o.wait(),t.join,lockSupport.park | ||
o.notify,o.notifyAll,lockSupport.unpark | |||
让出cpu | |||
Blocked | 等待进入同步代码块的锁 | ||
Terminated | 线程执行结束 |
2.Sychronized
锁对象this | |||
锁方法,锁的是this | |||
静态方法。锁T.class | |||
是可重入锁 | 一个同步方法可以调用另外一个同步方法,一个线程已经拥有某个对象的锁,再次申请的时候仍然会获得该对象的锁 | ||
程序出现异常,默认清空,锁会被释放 | |||
锁升级 | markword上记录线程id | ||
如果线程争用 升级为 自旋锁 | 用户态 | ||
占用Cpu,但是不占用操作系统 | |||
执行时间短,线程数量少,适合自旋锁 | |||
旋10次之后,拿不到,升级为重量级锁 | |||
synchronized(Object) | 不能用String常量,Integer,Long | ||
Volatile | 保证线程可见性 | MESI | |
Cpu缓存一致性协议 | |||
禁止指令重排序 | DCL单例Double check Lock | ||
对象创建过程 | 申请内存 | ||
初始化对象 | |||
为对象赋值 | |||
不能保证原子性 | |||
wait | 线程锁定 | ||
notify | 线程唤醒 |
3.容器
Connection | List | ArrayList | ||
LinkedList | ||||
线程安全 | CopyOnWriteArrayList-写时复制 | 应用:读特别多,写很少 | ||
Vector | Stack | |||
Set | HashSet | LinkedHashSet | ||
SortedSet | TreeSet | |||
线程安全 | ConcurrentSkipListSet | |||
CopyOnWriteArraySet | ||||
EnumSet | ||||
Queue | Deque | ArrayDeque | ||
BlockingDeque | LinkedBlockingDeque | |||
BlockingQueue | 阻塞 | put | ||
take | queue中没有,使用take阻塞 | |||
SynchronousQueue | ||||
DelayQueue | 按时间排序的队列 | |||
ProtityBlockingQueue | ||||
TransferQueue | LinkedTransferQueue | transfer() | ||
ConcurrentLinkedQueue | ||||
与List差异:添加了一些线程友好的Api | poll | |||
offer | ||||
peek | ||||
AstractQueue | ProtityQueue | 排序输出 | ||
二叉树,小顶堆 | ||||
Map | HashMap | LinkedHashMap | ||
TreeMap | ||||
IdentityHashMap | ||||
线程安全 | ConcurrentHashMap | |||
ConcurrentSkipListMap | 有序,支持并发 | |||
多层链表,加速查询 | ||||
TreeMap做CAS太复杂,所以产生跳表 | ||||
WeakHashMap |
4.线程池
ThreadPool与Executor |
||
ExecuteService | ||
Executors | ||
异步调用Future | ||
Callable-带返回值的Runnable | ||
ParallelStreamAPI | ||
常用线程池-Executors | Executors.newFixedThreadPool() | |
Executors.newCachedThreadPool() | ||
Executors.newSingleThreadExecutor() | 创建单一线程池 | |
Executors.newScheduledThreadPool() | ||
Executors.newWorkStealingPool() | ForkJoinPool() | |
[http://cdn.processon.com/5ed865151e0853199b4e18eb?e=1591243558&token=trhI0BY8QfVrIGn9nENop6JAc6l5nZuxhjQ62UfM:mwXuBZrK8nzJ11iucTd_QTc6S04=] |
|
5.java的引用类型
强 | ||
软SoftReference | 对象只有一个软引用,只有堆内存不够的时候才会回收 | |
-Xms 20M -Xmx20M堆内存最大,最小 | ||
主要用作缓存 | ||
弱WeakReference | 可以被gc立刻回收 | |
有强引用,引用断开,立刻就会回收 | ||
用在容器里 | ||
典型:ThreadLocal | 对象不再使用,必须remove()不然会引起内存泄露 | |
虚PhantomReference | 应用在jvm | |
get方法拿不到值 | ||
引用断开,会放到队列里,回收对外内存 |
6.JUC同步工具
cas自旋原理 | 实现方式CAS | 无锁优化,自旋 | |||
Actomic都是cas方式 |
[http://cdn.processon.com/5ede63441e0853263718f02e?e=1591636308&token=trhI0BY8QfVrIGn9nENop6JAc6l5nZuxh jQ62UfM:jhpGxpqYdJl432Yp0talw4SCKJk=] |
||||
Compare and Set | |||||
cup原语支持,不会被打断,保证线程安全 | |||||
ABA问题 | 添加版本号 | ||||
基础类型无所谓 | |||||
引用类型,对象会变化 | |||||
通过Unsafe类实现 | 可以操作jvm的内存 | ||||
等同于C c++的指针 | |||||
ReentrantLock-可重入锁 | lock.lock()->锁定,lock.unlock()->解锁 | ||||
lock.tryLock(time,TimeUnit.type)->time内尝试获得锁,获取不到放弃 | |||||
lock.lockInterruptibly()->可以对interrupt()方法做出响应,可以被打断加锁 | |||||
new ReentrantLock(true);->参数为true表示公平锁 | |||||
可以添加Condition,精确指定哪个线程被唤醒 | |||||
必须手动解锁,在finally执行unlock() | |||||
AQS-AbstractQueuedSynchronizer | 维护一个volatile的state | ||||
state控制一个存储Thread的双向链表。向链表里添加thread是通过compareAndsetState | |||||
ThreadLocal | set | Thread.currendtThread.map(ThreadLocal,person) | |||
设到了当前线程的map里 | |||||
线程操作自己的副本,不共享 | |||||
应用Spring的声明式事务,保证同一个Connection | |||||
AQS是一种提供了原子式管理同步状态、阻塞和唤醒线程功能以及队列模型的简单框架 | |||||
java的引用类型 | 强 | ||||
软SoftReference | 对象只有一个软引用,只有堆内存不够的时候才会回收 | ||||
-Xms 20M -Xmx20M堆内存最大,最小 | |||||
主要用作缓存 | |||||
弱WeakReference | 可以被gc立刻回收 | ||||
有强引用,引用断开,立刻就会回收 | |||||
用在容器里 | |||||
典型:ThreadLocal | 对象不再使用,必须remove()不然会引起内存泄露 | ||||
虚PhantomReference | 应用在jvm | ||||
get方法拿不到值 | |||||
引用断开,会放到队列里,回收对外内存 | |||||
[http://cdn.processon.com/5ee0ff6b5653bb29258fce2e?e=1591807356&token=trhI0BY8QfVrIGn9nENop6JAc6l5nZuxhjQ62UfM:2eV6A9oUa9tuy9htgd2K48Fj3bM=] | |||||
Condition条件等待与通知 | |||||
CountDownLatch-门栓 | latch.await()-->等待 | ||||
latch.countDown() | |||||
倒数 | |||||
CyclicBarrier-循环栅栏 | parties->满xx发车 | ||||
barrier.await()->等待 | |||||
复杂操作:1.数据库,2.网络,3.文件 并发操作:-线程-操作 线程-操作 |
|||||
Semaphore-信号灯 | permit:int | ||||
acquire();获得锁->信号量-1 | |||||
release();->释放锁,信号量+1 | |||||
限流 | |||||
车道和收费站 | |||||
Semaphore与Lock的区别 | |||||
Exchanger | 2个线程间交换数据 | ||||
LockSupport | 实现当前线程阻塞和唤醒 | ||||
park(); | |||||
unpark();可以先于park()执行 | |||||
Phaser-多阶段栅栏1.7 | 遗传算法 | ||||
phaser.bulkRegister()->注册数量 | |||||
phaser.arriveAndAwaitAdvance();->到达后等待往下走 | |||||
重新onAdvanc()->前进 | |||||
phaser.arriveAndDeregister() | |||||
ReadWriteLock-共享锁,排它锁 | readLock()->其他线程可以继续读 | ||||
writeLock() | |||||
子主题 | |||||
LongAdder | 使用分段锁 |